aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xfree86
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xfree86')
-rw-r--r--xorg-server/hw/xfree86/common/compiler.h6
-rw-r--r--xorg-server/hw/xfree86/common/xf86Config.c5062
-rw-r--r--xorg-server/hw/xfree86/common/xf86Configure.c1510
-rw-r--r--xorg-server/hw/xfree86/common/xf86Events.c1506
-rw-r--r--xorg-server/hw/xfree86/common/xf86Helper.c3898
-rw-r--r--xorg-server/hw/xfree86/common/xf86Init.c2998
-rw-r--r--xorg-server/hw/xfree86/common/xf86Module.h424
-rw-r--r--xorg-server/hw/xfree86/common/xf86Option.c1832
-rw-r--r--xorg-server/hw/xfree86/common/xf86RandR.c970
-rw-r--r--xorg-server/hw/xfree86/common/xf86Xinput.c2804
-rw-r--r--xorg-server/hw/xfree86/common/xf86sbusBus.c1428
-rw-r--r--xorg-server/hw/xfree86/common/xf86xv.c4380
-rw-r--r--xorg-server/hw/xfree86/ddc/ddcProperty.c248
-rw-r--r--xorg-server/hw/xfree86/dri/dri.c4992
-rw-r--r--xorg-server/hw/xfree86/dri/xf86dri.c1324
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.c2472
-rw-r--r--xorg-server/hw/xfree86/fbdevhw/fbdevhw.c1810
-rw-r--r--xorg-server/hw/xfree86/loader/Makefile.am66
-rw-r--r--xorg-server/hw/xfree86/loader/loadmod.c2506
-rw-r--r--xorg-server/hw/xfree86/loader/sdksyms.sh850
-rw-r--r--xorg-server/hw/xfree86/man/xorg.conf.man4970
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Crtc.h1944
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Cursors.c1376
-rw-r--r--xorg-server/hw/xfree86/modes/xf86RandR12.c3646
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Rotate.c1050
-rw-r--r--xorg-server/hw/xfree86/os-support/bsd/bsd_init.c1512
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/lnx_init.c690
-rw-r--r--xorg-server/hw/xfree86/ramdac/xf86Cursor.c950
-rw-r--r--xorg-server/hw/xfree86/vbe/vbe.c2178
29 files changed, 29701 insertions, 29701 deletions
diff --git a/xorg-server/hw/xfree86/common/compiler.h b/xorg-server/hw/xfree86/common/compiler.h
index 9e00d7571..9c9bac6ba 100644
--- a/xorg-server/hw/xfree86/common/compiler.h
+++ b/xorg-server/hw/xfree86/common/compiler.h
@@ -86,7 +86,7 @@
# endif
# endif /* __inline__ */
# ifndef __inline
-# if defined(__GNUC__)
+# if defined(__GNUC__) || defined(_MSC_VER)
/* gcc has __inline */
# elif defined(__HIGHC__)
# define __inline _Inline
@@ -1525,10 +1525,10 @@ inl(unsigned short port)
# define asm __asm
# endif
# endif
-# if !defined(__SUNPRO_C)
+# if !defined(__SUNPRO_C) && !defined(_MSC_VER)
# include <sys/inline.h>
# endif
-# if !defined(__HIGHC__) && !defined(__SUNPRO_C) || \
+# if (!defined(__HIGHC__) && !defined(__SUNPRO_C) && !defined(_MSC_VER)) || \
defined(__USLC__)
# pragma asm partial_optimization outl
# pragma asm partial_optimization outw
diff --git a/xorg-server/hw/xfree86/common/xf86Config.c b/xorg-server/hw/xfree86/common/xf86Config.c
index 114bdc3a3..4047350c4 100644
--- a/xorg-server/hw/xfree86/common/xf86Config.c
+++ b/xorg-server/hw/xfree86/common/xf86Config.c
@@ -1,2531 +1,2531 @@
-/*
- * Loosely based on code bearing the following copyright:
- *
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- */
-
-/*
- * Copyright 1992-2003 by The XFree86 Project, Inc.
- * Copyright 1997 by Metro Link, 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).
- */
-
-/*
- *
- * Authors:
- * Dirk Hohndel <hohndel@XFree86.Org>
- * David Dawes <dawes@XFree86.Org>
- * Marc La France <tsi@XFree86.Org>
- * Egbert Eich <eich@XFree86.Org>
- * ... and others
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#ifdef XF86DRI
-#include <sys/types.h>
-#include <grp.h>
-#endif
-
-#include "xf86.h"
-#include "xf86Parser.h"
-#include "xf86tokens.h"
-#include "xf86Config.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#include "configProcs.h"
-#include "globals.h"
-#include "extension.h"
-#include "xf86pciBus.h"
-
-#include "xf86Xinput.h"
-
-#include "xkbsrv.h"
-
-#include "picture.h"
-
-/*
- * These paths define the way the config file search is done. The escape
- * sequences are documented in parser/scan.c.
- */
-#ifndef ROOT_CONFIGPATH
-#define ROOT_CONFIGPATH "%A," "%R," \
- "/etc/X11/%R," "%P/etc/X11/%R," \
- "%E," "%F," \
- "/etc/X11/%F," "%P/etc/X11/%F," \
- "/etc/X11/%X," "/etc/%X," \
- "%P/etc/X11/%X.%H," \
- "%P/etc/X11/%X," \
- "%P/lib/X11/%X.%H," \
- "%P/lib/X11/%X"
-#endif
-#ifndef USER_CONFIGPATH
-#define USER_CONFIGPATH "/etc/X11/%S," "%P/etc/X11/%S," \
- "/etc/X11/%G," "%P/etc/X11/%G," \
- "/etc/X11/%X," "/etc/%X," \
- "%P/etc/X11/%X.%H," \
- "%P/etc/X11/%X," \
- "%P/lib/X11/%X.%H," \
- "%P/lib/X11/%X"
-#endif
-#ifndef ROOT_CONFIGDIRPATH
-#define ROOT_CONFIGDIRPATH "%A," "%R," \
- "/etc/X11/%R," "%C/X11/%R," \
- "/etc/X11/%X," "%C/X11/%X"
-#endif
-#ifndef USER_CONFIGDIRPATH
-#define USER_CONFIGDIRPATH "/etc/X11/%R," "%C/X11/%R," \
- "/etc/X11/%X," "%C/X11/%X"
-#endif
-#ifndef SYS_CONFIGDIRPATH
-#define SYS_CONFIGDIRPATH "/usr/share/X11/%X," "%D/X11/%X"
-#endif
-#ifndef PROJECTROOT
-#define PROJECTROOT "/usr/X11R6"
-#endif
-
-static ModuleDefault ModuleDefaults[] = {
- {.name = "extmod", .toLoad = TRUE, .load_opt=NULL},
-#ifdef DBE
- {.name = "dbe", .toLoad = TRUE, .load_opt=NULL},
-#endif
-#ifdef GLXEXT
- {.name = "glx", .toLoad = TRUE, .load_opt=NULL},
-#endif
-#ifdef XRECORD
- {.name = "record", .toLoad = TRUE, .load_opt=NULL},
-#endif
-#ifdef XF86DRI
- {.name = "dri", .toLoad = TRUE, .load_opt=NULL},
-#endif
-#ifdef DRI2
- {.name = "dri2", .toLoad = TRUE, .load_opt=NULL},
-#endif
- {.name = NULL, .toLoad = FALSE, .load_opt=NULL}
-};
-
-
-/* Forward declarations */
-static Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen,
- int scrnum, MessageType from);
-static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor);
-static Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device,
- Bool active);
-static Bool configInput(InputInfoPtr pInfo, XF86ConfInputPtr conf_input,
- MessageType from);
-static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display);
-static Bool addDefaultModes(MonPtr monitorp);
-#ifdef XF86DRI
-static void configDRI(XF86ConfDRIPtr drip);
-#endif
-static void configExtensions(XF86ConfExtensionsPtr conf_ext);
-
-/*
- * xf86GetPathElem --
- * Extract a single element from the font path string starting at
- * pnt. The font path element will be returned, and pnt will be
- * updated to point to the start of the next element, or set to
- * NULL if there are no more.
- */
-static char *
-xf86GetPathElem(char **pnt)
-{
- char *p1;
-
- p1 = *pnt;
- *pnt = index(*pnt, ',');
- if (*pnt != NULL) {
- **pnt = '\0';
- *pnt += 1;
- }
- return p1;
-}
-
-/*
- * xf86ValidateFontPath --
- * Validates the user-specified font path. Each element that
- * begins with a '/' is checked to make sure the directory exists.
- * If the directory exists, the existence of a file named 'fonts.dir'
- * is checked. If either check fails, an error is printed and the
- * element is removed from the font path.
- */
-
-#define DIR_FILE "/fonts.dir"
-static char *
-xf86ValidateFontPath(char *path)
-{
- char *tmp_path, *out_pnt, *path_elem, *next, *p1, *dir_elem;
- struct stat stat_buf;
- int flag;
- int dirlen;
-
- tmp_path = calloc(1,strlen(path)+1);
- out_pnt = tmp_path;
- path_elem = NULL;
- next = path;
- while (next != NULL) {
- path_elem = xf86GetPathElem(&next);
- if (*path_elem == '/') {
- dir_elem = xnfcalloc(1, strlen(path_elem) + 1);
- if ((p1 = strchr(path_elem, ':')) != 0)
- dirlen = p1 - path_elem;
- else
- dirlen = strlen(path_elem);
- strncpy(dir_elem, path_elem, dirlen);
- dir_elem[dirlen] = '\0';
- flag = stat(dir_elem, &stat_buf);
- if (flag == 0)
- if (!S_ISDIR(stat_buf.st_mode))
- flag = -1;
- if (flag != 0) {
- xf86Msg(X_WARNING, "The directory \"%s\" does not exist.\n", dir_elem);
- xf86ErrorF("\tEntry deleted from font path.\n");
- free(dir_elem);
- continue;
- }
- else {
- XNFasprintf(&p1, "%s%s", dir_elem, DIR_FILE);
- flag = stat(p1, &stat_buf);
- if (flag == 0)
- if (!S_ISREG(stat_buf.st_mode))
- flag = -1;
- free(p1);
- if (flag != 0) {
- xf86Msg(X_WARNING,
- "`fonts.dir' not found (or not valid) in \"%s\".\n",
- dir_elem);
- xf86ErrorF("\tEntry deleted from font path.\n");
- xf86ErrorF("\t(Run 'mkfontdir' on \"%s\").\n", dir_elem);
- free(dir_elem);
- continue;
- }
- }
- free(dir_elem);
- }
-
- /*
- * Either an OK directory, or a font server name. So add it to
- * the path.
- */
- if (out_pnt != tmp_path)
- *out_pnt++ = ',';
- strcat(out_pnt, path_elem);
- out_pnt += strlen(path_elem);
- }
- return tmp_path;
-}
-
-
-/*
- * use the datastructure that the parser provides and pick out the parts
- * that we need at this point
- */
-char **
-xf86ModulelistFromConfig(pointer **optlist)
-{
- int count = 0, i = 0;
- char **modulearray;
- char *ignore[] = { "GLcore", "speedo", "bitmap", "drm",
- "freetype", "type1",
- NULL };
- pointer *optarray;
- XF86LoadPtr modp;
- Bool found;
-
- /*
- * make sure the config file has been parsed and that we have a
- * ModulePath set; if no ModulePath was given, use the default
- * ModulePath
- */
- if (xf86configptr == NULL) {
- xf86Msg(X_ERROR, "Cannot access global config data structure\n");
- return NULL;
- }
-
- if (xf86configptr->conf_modules) {
- /* Walk the disable list and let people know what we've parsed to
- * not be loaded
- */
- modp = xf86configptr->conf_modules->mod_disable_lst;
- while (modp) {
- xf86Msg(X_WARNING, "\"%s\" will not be loaded unless you've specified it to be loaded elsewhere.\n", modp->load_name);
- modp = (XF86LoadPtr) modp->list.next;
- }
- /*
- * Walk the default settings table. For each module listed to be
- * loaded, make sure it's in the mod_load_lst. If it's not, make
- * sure it's not in the mod_no_load_lst. If it's not disabled,
- * append it to mod_load_lst
- */
- for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
- if (ModuleDefaults[i].toLoad == FALSE) {
- xf86Msg(X_WARNING, "\"%s\" is not to be loaded by default. Skipping.\n", ModuleDefaults[i].name);
- continue;
- }
- found = FALSE;
- modp = xf86configptr->conf_modules->mod_load_lst;
- while (modp) {
- if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
- xf86Msg(X_INFO, "\"%s\" will be loaded. This was enabled by default and also specified in the config file.\n", ModuleDefaults[i].name);
- found = TRUE;
- break;
- }
- modp = (XF86LoadPtr) modp->list.next;
- }
- if (found == FALSE) {
- modp = xf86configptr->conf_modules->mod_disable_lst;
- while (modp) {
- if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
- xf86Msg(X_INFO, "\"%s\" will be loaded even though the default is to disable it.\n", ModuleDefaults[i].name);
- found = TRUE;
- break;
- }
- modp = (XF86LoadPtr) modp->list.next;
- }
- }
- if (found == FALSE) {
- XF86LoadPtr ptr = (XF86LoadPtr)xf86configptr->conf_modules;
- xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
- xf86Msg(X_INFO, "\"%s\" will be loaded by default.\n", ModuleDefaults[i].name);
- }
- }
- } else {
- xf86configptr->conf_modules = xnfcalloc(1, sizeof(XF86ConfModuleRec));
- for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
- if (ModuleDefaults[i].toLoad == TRUE) {
- XF86LoadPtr ptr = (XF86LoadPtr)xf86configptr->conf_modules;
- xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
- }
- }
- }
-
- /*
- * Walk the list of modules in the "Module" section to determine how
- * many we have.
- */
- modp = xf86configptr->conf_modules->mod_load_lst;
- while (modp) {
- for (i = 0; ignore[i]; i++) {
- if (strcmp(modp->load_name, ignore[i]) == 0)
- modp->ignore = 1;
- }
- if (!modp->ignore)
- count++;
- modp = (XF86LoadPtr) modp->list.next;
- }
-
- /*
- * allocate the memory and walk the list again to fill in the pointers
- */
- modulearray = xnfalloc((count + 1) * sizeof(char*));
- optarray = xnfalloc((count + 1) * sizeof(pointer));
- count = 0;
- if (xf86configptr->conf_modules) {
- modp = xf86configptr->conf_modules->mod_load_lst;
- while (modp) {
- if (!modp->ignore) {
- modulearray[count] = modp->load_name;
- optarray[count] = modp->load_opt;
- count++;
- }
- modp = (XF86LoadPtr) modp->list.next;
- }
- }
- modulearray[count] = NULL;
- optarray[count] = NULL;
- if (optlist)
- *optlist = optarray;
- else
- free(optarray);
- return modulearray;
-}
-
-
-char **
-xf86DriverlistFromConfig(void)
-{
- int count = 0;
- int j;
- char **modulearray;
- screenLayoutPtr slp;
-
- /*
- * make sure the config file has been parsed and that we have a
- * ModulePath set; if no ModulePath was given, use the default
- * ModulePath
- */
- if (xf86configptr == NULL) {
- xf86Msg(X_ERROR, "Cannot access global config data structure\n");
- return NULL;
- }
-
- /*
- * Walk the list of driver lines in active "Device" sections to
- * determine now many implicitly loaded modules there are.
- *
- */
- if (xf86ConfigLayout.screens) {
- slp = xf86ConfigLayout.screens;
- while ((slp++)->screen) {
- count++;
- }
- }
-
- /*
- * Handle the set of inactive "Device" sections.
- */
- j = 0;
- while (xf86ConfigLayout.inactives[j++].identifier)
- count++;
-
- if (count == 0)
- return NULL;
-
- /*
- * allocate the memory and walk the list again to fill in the pointers
- */
- modulearray = xnfalloc((count + 1) * sizeof(char*));
- count = 0;
- slp = xf86ConfigLayout.screens;
- while (slp->screen) {
- modulearray[count] = slp->screen->device->driver;
- count++;
- slp++;
- }
-
- j = 0;
-
- while (xf86ConfigLayout.inactives[j].identifier)
- modulearray[count++] = xf86ConfigLayout.inactives[j++].driver;
-
- modulearray[count] = NULL;
-
- /* Remove duplicates */
- for (count = 0; modulearray[count] != NULL; count++) {
- int i;
-
- for (i = 0; i < count; i++)
- if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
- modulearray[count] = "";
- break;
- }
- }
- return modulearray;
-}
-
-char **
-xf86InputDriverlistFromConfig(void)
-{
- int count = 0;
- char **modulearray;
- InputInfoPtr *idp;
-
- /*
- * make sure the config file has been parsed and that we have a
- * ModulePath set; if no ModulePath was given, use the default
- * ModulePath
- */
- if (xf86configptr == NULL) {
- xf86Msg(X_ERROR, "Cannot access global config data structure\n");
- return NULL;
- }
-
- /*
- * Walk the list of driver lines in active "InputDevice" sections to
- * determine now many implicitly loaded modules there are.
- */
- if (xf86ConfigLayout.inputs) {
- idp = xf86ConfigLayout.inputs;
- while (*idp) {
- count++;
- idp++;
- }
- }
-
- if (count == 0)
- return NULL;
-
- /*
- * allocate the memory and walk the list again to fill in the pointers
- */
- modulearray = xnfalloc((count + 1) * sizeof(char*));
- count = 0;
- idp = xf86ConfigLayout.inputs;
- while (idp && *idp) {
- modulearray[count] = (*idp)->driver;
- count++;
- idp++;
- }
- modulearray[count] = NULL;
-
- /* Remove duplicates */
- for (count = 0; modulearray[count] != NULL; count++) {
- int i;
-
- for (i = 0; i < count; i++)
- if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
- modulearray[count] = "";
- break;
- }
- }
- return modulearray;
-}
-
-static void
-fixup_video_driver_list(char **drivers)
-{
- static const char *fallback[4] = { "vesa", "fbdev", "wsfb", NULL };
- char **end, **drv;
- char *x;
- int i;
-
- /* walk to the end of the list */
- for (end = drivers; *end && **end; end++) ;
- end--;
-
- /*
- * for each of the fallback drivers, if we find it in the list,
- * swap it with the last available non-fallback driver.
- */
- for (i = 0; fallback[i]; i++) {
- for (drv = drivers; drv != end; drv++) {
- if (strstr(*drv, fallback[i])) {
- x = *drv; *drv = *end; *end = x;
- end--;
- break;
- }
- }
- }
-}
-
-static char **
-GenerateDriverlist(char * dirname)
-{
- char **ret;
- const char *subdirs[] = { dirname, NULL };
- static const char *patlist[] = {"(.*)_drv\\.so", NULL};
- ret = LoaderListDirs(subdirs, patlist);
-
- /* fix up the probe order for video drivers */
- if (strstr(dirname, "drivers") && ret != NULL)
- fixup_video_driver_list(ret);
-
- return ret;
-}
-
-char **
-xf86DriverlistFromCompile(void)
-{
- static char **driverlist = NULL;
-
- if (!driverlist)
- driverlist = GenerateDriverlist("drivers");
-
- return driverlist;
-}
-
-/*
- * xf86ConfigError --
- * Print a READABLE ErrorMessage!!! All information that is
- * available is printed.
- */
-static void
-xf86ConfigError(char *msg, ...)
-{
- va_list ap;
-
- ErrorF("\nConfig Error:\n");
- va_start(ap, msg);
- VErrorF(msg, ap);
- va_end(ap);
- ErrorF("\n");
- return;
-}
-
-static void
-configFiles(XF86ConfFilesPtr fileconf)
-{
- MessageType pathFrom;
- Bool must_copy;
- int size, countDirs;
- char *temp_path, *log_buf, *start, *end;
-
- /* FontPath */
- must_copy = TRUE;
-
- temp_path = defaultFontPath ? defaultFontPath : "";
- if (xf86fpFlag)
- pathFrom = X_CMDLINE;
- else if (fileconf && fileconf->file_fontpath) {
- pathFrom = X_CONFIG;
- if (xf86Info.useDefaultFontPath) {
- if (asprintf(&defaultFontPath, "%s%s%s", fileconf->file_fontpath,
- *temp_path ? "," : "", temp_path) == -1)
- defaultFontPath = NULL;
- else
- must_copy = FALSE;
- }
- else
- defaultFontPath = fileconf->file_fontpath;
- }
- else
- pathFrom = X_DEFAULT;
- temp_path = defaultFontPath ? defaultFontPath : "";
-
- /* xf86ValidateFontPath modifies its argument, but returns a copy of it. */
- temp_path = must_copy ? xnfstrdup(defaultFontPath) : defaultFontPath;
- defaultFontPath = xf86ValidateFontPath(temp_path);
- free(temp_path);
-
- /* make fontpath more readable in the logfiles */
- countDirs = 1;
- temp_path = defaultFontPath;
- while ((temp_path = index(temp_path, ',')) != NULL) {
- countDirs++;
- temp_path++;
- }
-
- log_buf = xnfalloc(strlen(defaultFontPath) + (2 * countDirs) + 1);
- temp_path = log_buf;
- start = defaultFontPath;
- while((end = index(start, ',')) != NULL) {
- size = (end - start) + 1;
- *(temp_path++) = '\t';
- strncpy(temp_path, start, size);
- temp_path += size;
- *(temp_path++) = '\n';
- start += size;
- }
- /* copy last entry */
- *(temp_path++) = '\t';
- strcpy(temp_path, start);
- xf86Msg(pathFrom, "FontPath set to:\n%s\n", log_buf);
- free(log_buf);
-
- /* ModulePath */
-
- if (fileconf) {
- if (xf86ModPathFrom != X_CMDLINE && fileconf->file_modulepath) {
- xf86ModulePath = fileconf->file_modulepath;
- xf86ModPathFrom = X_CONFIG;
- }
- }
-
- xf86Msg(xf86ModPathFrom, "ModulePath set to \"%s\"\n", xf86ModulePath);
-
- if (!xf86xkbdirFlag && fileconf && fileconf->file_xkbdir) {
- XkbBaseDirectory = fileconf->file_xkbdir;
- xf86Msg(X_CONFIG, "XKB base directory set to \"%s\"\n",
- XkbBaseDirectory);
- }
-#if 0
- /* LogFile */
- /*
- * XXX The problem with this is that the log file is already open.
- * One option might be to copy the exiting contents to the new location.
- * and re-open it. The down side is that the default location would
- * already have been overwritten. Another option would be to start with
- * unique temporary location, then copy it once the correct name is known.
- * A problem with this is what happens if the server exits before that
- * happens.
- */
- if (xf86LogFileFrom == X_DEFAULT && fileconf->file_logfile) {
- xf86LogFile = fileconf->file_logfile;
- xf86LogFileFrom = X_CONFIG;
- }
-#endif
-
- return;
-}
-
-typedef enum {
- FLAG_NOTRAPSIGNALS,
- FLAG_DONTVTSWITCH,
- FLAG_DONTZAP,
- FLAG_DONTZOOM,
- FLAG_DISABLEVIDMODE,
- FLAG_ALLOWNONLOCAL,
- FLAG_ALLOWMOUSEOPENFAIL,
- FLAG_VTSYSREQ,
- FLAG_SAVER_BLANKTIME,
- FLAG_DPMS_STANDBYTIME,
- FLAG_DPMS_SUSPENDTIME,
- FLAG_DPMS_OFFTIME,
- FLAG_PIXMAP,
- FLAG_PC98,
- FLAG_NOPM,
- FLAG_XINERAMA,
- FLAG_LOG,
- FLAG_RENDER_COLORMAP_MODE,
- FLAG_RANDR,
- FLAG_AIGLX,
- FLAG_IGNORE_ABI,
- FLAG_ALLOW_EMPTY_INPUT,
- FLAG_USE_DEFAULT_FONT_PATH,
- FLAG_AUTO_ADD_DEVICES,
- FLAG_AUTO_ENABLE_DEVICES,
- FLAG_GLX_VISUALS,
- FLAG_DRI2,
- FLAG_USE_SIGIO
-} FlagValues;
-
-/**
- * NOTE: the last value for each entry is NOT the default. It is set to TRUE
- * if the parser found the option in the config file.
- */
-static OptionInfoRec FlagOptions[] = {
- { FLAG_NOTRAPSIGNALS, "NoTrapSignals", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_DONTVTSWITCH, "DontVTSwitch", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_DONTZAP, "DontZap", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_DONTZOOM, "DontZoom", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_DISABLEVIDMODE, "DisableVidModeExtension", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_ALLOWNONLOCAL, "AllowNonLocalXvidtune", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_ALLOWMOUSEOPENFAIL, "AllowMouseOpenFail", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_VTSYSREQ, "VTSysReq", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_SAVER_BLANKTIME, "BlankTime" , OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_DPMS_STANDBYTIME, "StandbyTime", OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_DPMS_SUSPENDTIME, "SuspendTime", OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_DPMS_OFFTIME, "OffTime", OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_PIXMAP, "Pixmap", OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_PC98, "PC98", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_NOPM, "NoPM", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_XINERAMA, "Xinerama", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_LOG, "Log", OPTV_STRING,
- {0}, FALSE },
- { FLAG_RENDER_COLORMAP_MODE, "RenderColormapMode", OPTV_STRING,
- {0}, FALSE },
- { FLAG_RANDR, "RandR", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_AIGLX, "AIGLX", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_IGNORE_ABI, "IgnoreABI", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_USE_DEFAULT_FONT_PATH, "UseDefaultFontPath", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_AUTO_ADD_DEVICES, "AutoAddDevices", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_AUTO_ENABLE_DEVICES, "AutoEnableDevices", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_GLX_VISUALS, "GlxVisuals", OPTV_STRING,
- {0}, FALSE },
- { FLAG_DRI2, "DRI2", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_USE_SIGIO, "UseSIGIO", OPTV_BOOLEAN,
- {0}, FALSE },
- { -1, NULL, OPTV_NONE,
- {0}, FALSE },
-};
-
-#ifdef SUPPORT_PC98
-static Bool
-detectPC98(void)
-{
- unsigned char buf[2];
-
- if (xf86ReadBIOS(0xf8000, 0xe80, buf, 2) != 2)
- return FALSE;
- if ((buf[0] == 0x98) && (buf[1] == 0x21))
- return TRUE;
- else
- return FALSE;
-}
-#endif
-
-static Bool
-configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
-{
- XF86OptionPtr optp, tmp;
- int i;
- Pix24Flags pix24 = Pix24DontCare;
- Bool value;
- MessageType from;
- const char *s;
- XkbRMLVOSet set;
- /* Default options. */
- set.rules = "base";
- set.model = "pc105";
- set.layout = "us";
- set.variant = NULL;
- set.options = NULL;
-
- /*
- * Merge the ServerLayout and ServerFlags options. The former have
- * precedence over the latter.
- */
- optp = NULL;
- if (flagsconf && flagsconf->flg_option_lst)
- optp = xf86optionListDup(flagsconf->flg_option_lst);
- if (layoutopts) {
- tmp = xf86optionListDup(layoutopts);
- if (optp)
- optp = xf86optionListMerge(optp, tmp);
- else
- optp = tmp;
- }
-
- xf86ProcessOptions(-1, optp, FlagOptions);
-
- xf86GetOptValBool(FlagOptions, FLAG_NOTRAPSIGNALS, &xf86Info.notrapSignals);
- xf86GetOptValBool(FlagOptions, FLAG_DONTVTSWITCH, &xf86Info.dontVTSwitch);
- xf86GetOptValBool(FlagOptions, FLAG_DONTZAP, &xf86Info.dontZap);
- xf86GetOptValBool(FlagOptions, FLAG_DONTZOOM, &xf86Info.dontZoom);
-
- xf86GetOptValBool(FlagOptions, FLAG_IGNORE_ABI, &xf86Info.ignoreABI);
- if (xf86Info.ignoreABI) {
- xf86Msg(X_CONFIG, "Ignoring ABI Version\n");
- }
-
- if (xf86SIGIOSupported()) {
- xf86Info.useSIGIO = xf86ReturnOptValBool(FlagOptions, FLAG_USE_SIGIO, USE_SIGIO_BY_DEFAULT);
- if (xf86IsOptionSet(FlagOptions, FLAG_USE_SIGIO)) {
- from = X_CONFIG;
- } else {
- from = X_DEFAULT;
- }
- if (!xf86Info.useSIGIO) {
- xf86Msg(from, "Disabling SIGIO handlers for input devices\n");
- } else if (from == X_CONFIG) {
- xf86Msg(from, "Enabling SIGIO handlers for input devices\n");
- }
- } else {
- xf86Info.useSIGIO = FALSE;
- }
-
- if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_DEVICES)) {
- xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_DEVICES,
- &xf86Info.autoAddDevices);
- from = X_CONFIG;
- }
- else {
- from = X_DEFAULT;
- }
- xf86Msg(from, "%sutomatically adding devices\n",
- xf86Info.autoAddDevices ? "A" : "Not a");
-
- if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ENABLE_DEVICES)) {
- xf86GetOptValBool(FlagOptions, FLAG_AUTO_ENABLE_DEVICES,
- &xf86Info.autoEnableDevices);
- from = X_CONFIG;
- }
- else {
- from = X_DEFAULT;
- }
- xf86Msg(from, "%sutomatically enabling devices\n",
- xf86Info.autoEnableDevices ? "A" : "Not a");
-
- /*
- * Set things up based on the config file information. Some of these
- * settings may be overridden later when the command line options are
- * checked.
- */
-#ifdef XF86VIDMODE
- if (xf86GetOptValBool(FlagOptions, FLAG_DISABLEVIDMODE, &value))
- xf86Info.vidModeEnabled = !value;
- if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWNONLOCAL, &value))
- xf86Info.vidModeAllowNonLocal = value;
-#endif
-
- if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWMOUSEOPENFAIL, &value))
- xf86Info.allowMouseOpenFail = value;
-
- if (xf86GetOptValBool(FlagOptions, FLAG_VTSYSREQ, &value)) {
-#ifdef USE_VT_SYSREQ
- xf86Info.vtSysreq = value;
- xf86Msg(X_CONFIG, "VTSysReq %s\n", value ? "enabled" : "disabled");
-#else
- if (value)
- xf86Msg(X_WARNING, "VTSysReq is not supported on this OS\n");
-#endif
- }
-
- xf86Info.pmFlag = TRUE;
- if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value))
- xf86Info.pmFlag = !value;
- {
- if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) {
- if (!xf86NameCmp(s,"flush")) {
- xf86Msg(X_CONFIG, "Flushing logfile enabled\n");
- xf86Info.log = LogFlush;
- LogSetParameter(XLOG_FLUSH, TRUE);
- } else if (!xf86NameCmp(s,"sync")) {
- xf86Msg(X_CONFIG, "Syncing logfile enabled\n");
- xf86Info.log = LogSync;
- LogSetParameter(XLOG_FLUSH, TRUE);
- LogSetParameter(XLOG_SYNC, TRUE);
- } else {
- xf86Msg(X_WARNING,"Unknown Log option\n");
- }
- }
- }
-
- {
- if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))){
- int policy = PictureParseCmapPolicy (s);
- if (policy == PictureCmapPolicyInvalid)
- xf86Msg(X_WARNING, "Unknown colormap policy \"%s\"\n", s);
- else
- {
- xf86Msg(X_CONFIG, "Render colormap policy set to %s\n", s);
- PictureCmapPolicy = policy;
- }
- }
- }
-
-#ifdef RANDR
- xf86Info.disableRandR = FALSE;
- xf86Info.randRFrom = X_DEFAULT;
- if (xf86GetOptValBool(FlagOptions, FLAG_RANDR, &value)) {
- xf86Info.disableRandR = !value;
- xf86Info.randRFrom = X_CONFIG;
- }
-#endif
-
- xf86Info.aiglx = TRUE;
- xf86Info.aiglxFrom = X_DEFAULT;
- if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
- xf86Info.aiglx = value;
- xf86Info.aiglxFrom = X_CONFIG;
- }
-
-#ifdef GLXEXT
- xf86Info.glxVisuals = XF86_GlxVisualsTypical;
- xf86Info.glxVisualsFrom = X_DEFAULT;
- if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) {
- if (!xf86NameCmp(s, "minimal")) {
- xf86Info.glxVisuals = XF86_GlxVisualsMinimal;
- } else if (!xf86NameCmp(s, "typical")) {
- xf86Info.glxVisuals = XF86_GlxVisualsTypical;
- } else if (!xf86NameCmp(s, "all")) {
- xf86Info.glxVisuals = XF86_GlxVisualsAll;
- } else {
- xf86Msg(X_WARNING,"Unknown GlxVisuals option\n");
- }
- }
-
- if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
- xf86Info.aiglx = value;
- xf86Info.aiglxFrom = X_CONFIG;
- }
-#endif
-
- /* if we're not hotplugging, force some input devices to exist */
- xf86Info.forceInputDevices = !(xf86Info.autoAddDevices && xf86Info.autoEnableDevices);
-
- /* when forcing input devices, we use kbd. otherwise evdev, so use the
- * evdev rules set. */
-#if defined(linux)
- if (!xf86Info.forceInputDevices)
- set.rules = "evdev";
-#endif
- XkbSetRulesDflts(&set);
-
- xf86Info.useDefaultFontPath = TRUE;
- xf86Info.useDefaultFontPathFrom = X_DEFAULT;
- if (xf86GetOptValBool(FlagOptions, FLAG_USE_DEFAULT_FONT_PATH, &value)) {
- xf86Info.useDefaultFontPath = value;
- xf86Info.useDefaultFontPathFrom = X_CONFIG;
- }
-
-/* Make sure that timers don't overflow CARD32's after multiplying */
-#define MAX_TIME_IN_MIN (0x7fffffff / MILLI_PER_MIN)
-
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_SAVER_BLANKTIME, &i);
- if ((i >= 0) && (i < MAX_TIME_IN_MIN))
- ScreenSaverTime = defaultScreenSaverTime = i * MILLI_PER_MIN;
- else if (i != -1)
- xf86ConfigError("BlankTime value %d outside legal range of 0 - %d minutes",
- i, MAX_TIME_IN_MIN);
-
-#ifdef DPMSExtension
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_DPMS_STANDBYTIME, &i);
- if ((i >= 0) && (i < MAX_TIME_IN_MIN))
- DPMSStandbyTime = i * MILLI_PER_MIN;
- else if (i != -1)
- xf86ConfigError("StandbyTime value %d outside legal range of 0 - %d minutes",
- i, MAX_TIME_IN_MIN);
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_DPMS_SUSPENDTIME, &i);
- if ((i >= 0) && (i < MAX_TIME_IN_MIN))
- DPMSSuspendTime = i * MILLI_PER_MIN;
- else if (i != -1)
- xf86ConfigError("SuspendTime value %d outside legal range of 0 - %d minutes",
- i, MAX_TIME_IN_MIN);
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_DPMS_OFFTIME, &i);
- if ((i >= 0) && (i < MAX_TIME_IN_MIN))
- DPMSOffTime = i * MILLI_PER_MIN;
- else if (i != -1)
- xf86ConfigError("OffTime value %d outside legal range of 0 - %d minutes",
- i, MAX_TIME_IN_MIN);
-#endif
-
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_PIXMAP, &i);
- switch (i) {
- case 24:
- pix24 = Pix24Use24;
- break;
- case 32:
- pix24 = Pix24Use32;
- break;
- case -1:
- break;
- default:
- xf86ConfigError("Pixmap option's value (%d) must be 24 or 32\n", i);
- return FALSE;
- }
- if (xf86Pix24 != Pix24DontCare) {
- xf86Info.pixmap24 = xf86Pix24;
- xf86Info.pix24From = X_CMDLINE;
- } else if (pix24 != Pix24DontCare) {
- xf86Info.pixmap24 = pix24;
- xf86Info.pix24From = X_CONFIG;
- } else {
- xf86Info.pixmap24 = Pix24DontCare;
- xf86Info.pix24From = X_DEFAULT;
- }
-#ifdef SUPPORT_PC98
- if (xf86GetOptValBool(FlagOptions, FLAG_PC98, &value)) {
- xf86Info.pc98 = value;
- if (value) {
- xf86Msg(X_CONFIG, "Japanese PC98 architecture\n");
- }
- } else
- if (detectPC98()) {
- xf86Info.pc98 = TRUE;
- xf86Msg(X_PROBED, "Japanese PC98 architecture\n");
- }
-#endif
-
-#ifdef PANORAMIX
- from = X_DEFAULT;
- if (!noPanoramiXExtension)
- from = X_CMDLINE;
- else if (xf86GetOptValBool(FlagOptions, FLAG_XINERAMA, &value)) {
- noPanoramiXExtension = !value;
- from = X_CONFIG;
- }
- if (!noPanoramiXExtension)
- xf86Msg(from, "Xinerama: enabled\n");
-#endif
-
-#ifdef DRI2
- xf86Info.dri2 = FALSE;
- xf86Info.dri2From = X_DEFAULT;
- if (xf86GetOptValBool(FlagOptions, FLAG_DRI2, &value)) {
- xf86Info.dri2 = value;
- xf86Info.dri2From = X_CONFIG;
- }
-#endif
-
- return TRUE;
-}
-
-Bool xf86DRI2Enabled(void)
-{
- return xf86Info.dri2;
-}
-
-/*
- * Locate the core input devices. These can be specified/located in
- * the following ways, in order of priority:
- *
- * 1. The InputDevices named by the -pointer and -keyboard command line
- * options.
- * 2. The "CorePointer" and "CoreKeyboard" InputDevices referred to by
- * the active ServerLayout.
- * 3. The first InputDevices marked as "CorePointer" and "CoreKeyboard".
- * 4. The first InputDevices that use 'keyboard' or 'kbd' and a valid mouse
- * driver (mouse, synaptics, evdev, vmmouse, void)
- * 5. Default devices with an empty (default) configuration. These defaults
- * will reference the 'mouse' and 'keyboard' drivers.
- */
-
-static Bool
-checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
-{
- InputInfoPtr corePointer = NULL, coreKeyboard = NULL;
- Bool foundPointer = FALSE, foundKeyboard = FALSE;
- const char *pointerMsg = NULL, *keyboardMsg = NULL;
- InputInfoPtr *devs, /* iterator */
- indp;
- InputInfoRec 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 };
-
- /*
- * First check if a core pointer or core keyboard have been specified
- * in the active ServerLayout. If more than one is specified for either,
- * remove the core attribute from the later ones.
- */
- for (devs = servlayoutp->inputs; devs && *devs; devs++) {
- indp = *devs;
- if (indp->options &&
- 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;
-
- /* 1. Check for the -pointer command line option. */
- if (xf86PointerName) {
- confInput = xf86findInput(xf86PointerName,
- xf86configptr->conf_input_lst);
- if (!confInput) {
- xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
- xf86PointerName);
- return FALSE;
- }
- from = X_CMDLINE;
- /*
- * If one was already specified in the ServerLayout, it needs to be
- * 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--;
- }
- corePointer = NULL;
- foundPointer = TRUE;
- }
-
- /* 2. ServerLayout-specified core pointer. */
- if (corePointer) {
- foundPointer = TRUE;
- from = X_CONFIG;
- }
-
- /* 3. First core pointer device. */
- if (!foundPointer && (xf86Info.forceInputDevices || implicitLayout)) {
- XF86ConfInputPtr p;
-
- for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
- if (p->inp_option_lst &&
- xf86CheckBoolOption(p->inp_option_lst, "CorePointer", FALSE)) {
- confInput = p;
- foundPointer = TRUE;
- from = X_DEFAULT;
- pointerMsg = "first core pointer device";
- break;
- }
- }
- }
-
- /* 4. First pointer with an allowed mouse driver. */
- if (!foundPointer && xf86Info.forceInputDevices) {
- const char **driver = mousedrivers;
- confInput = xf86findInput(CONF_IMPLICIT_POINTER,
- xf86configptr->conf_input_lst);
- while (*driver && !confInput) {
- confInput = xf86findInputByDriver(*driver,
- xf86configptr->conf_input_lst);
- driver++;
- }
- if (confInput) {
- foundPointer = TRUE;
- from = X_DEFAULT;
- pointerMsg = "first mouse device";
- }
- }
-
- /* 5. Built-in default. */
- if (!foundPointer && xf86Info.forceInputDevices) {
- memset(&defPtr, 0, sizeof(defPtr));
- defPtr.inp_identifier = strdup("<default pointer>");
- defPtr.inp_driver = strdup("mouse");
- confInput = &defPtr;
- foundPointer = TRUE;
- from = X_DEFAULT;
- pointerMsg = "default mouse configuration";
- }
-
- /* 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));
- *devs[count - 1] = Pointer;
- devs[count - 1]->options =
- xf86addNewOption(devs[count -1]->options,
- xnfstrdup("CorePointer"), NULL);
- devs[count] = NULL;
- servlayoutp->inputs = devs;
- }
- }
-
- if (!foundPointer && xf86Info.forceInputDevices) {
- /* This shouldn't happen. */
- xf86Msg(X_ERROR, "Cannot locate a core pointer device.\n");
- 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));
- *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. */
- if (xf86KeyboardName) {
- confInput = xf86findInput(xf86KeyboardName,
- xf86configptr->conf_input_lst);
- if (!confInput) {
- xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
- xf86KeyboardName);
- return FALSE;
- }
- from = X_CMDLINE;
- /*
- * If one was already specified in the ServerLayout, it needs to be
- * 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--;
- }
- coreKeyboard = NULL;
- foundKeyboard = TRUE;
- }
-
- /* 2. ServerLayout-specified core keyboard. */
- if (coreKeyboard) {
- foundKeyboard = TRUE;
- from = X_CONFIG;
- }
-
- /* 3. First core keyboard device. */
- if (!foundKeyboard && (xf86Info.forceInputDevices || implicitLayout)) {
- XF86ConfInputPtr p;
-
- for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
- if (p->inp_option_lst &&
- xf86CheckBoolOption(p->inp_option_lst, "CoreKeyboard", FALSE)) {
- confInput = p;
- foundKeyboard = TRUE;
- from = X_DEFAULT;
- keyboardMsg = "first core keyboard device";
- break;
- }
- }
- }
-
- /* 4. First keyboard with 'keyboard' or 'kbd' as the driver. */
- if (!foundKeyboard && xf86Info.forceInputDevices) {
- confInput = xf86findInput(CONF_IMPLICIT_KEYBOARD,
- xf86configptr->conf_input_lst);
- if (!confInput) {
- confInput = xf86findInputByDriver("kbd",
- xf86configptr->conf_input_lst);
- }
- if (confInput) {
- foundKeyboard = TRUE;
- from = X_DEFAULT;
- keyboardMsg = "first keyboard device";
- }
- }
-
- /* 5. Built-in default. */
- if (!foundKeyboard && xf86Info.forceInputDevices) {
- memset(&defKbd, 0, sizeof(defKbd));
- defKbd.inp_identifier = strdup("<default keyboard>");
- defKbd.inp_driver = strdup("kbd");
- confInput = &defKbd;
- foundKeyboard = TRUE;
- keyboardMsg = "default keyboard configuration";
- from = X_DEFAULT;
- }
-
- /* 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));
- *devs[count - 1] = Keyboard;
- devs[count - 1]->options =
- xf86addNewOption(devs[count - 1]->options,
- xnfstrdup("CoreKeyboard"), NULL);
- devs[count] = NULL;
- servlayoutp->inputs = devs;
- }
- }
-
- if (!foundKeyboard && xf86Info.forceInputDevices) {
- /* This shouldn't happen. */
- xf86Msg(X_ERROR, "Cannot locate a core keyboard device.\n");
- return FALSE;
- }
-
- if (pointerMsg) {
- if (implicitLayout)
- xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
- pointerMsg);
- else
- xf86Msg(X_DEFAULT, "The core pointer device wasn't specified "
- "explicitly in the layout.\n"
- "\tUsing the %s.\n", pointerMsg);
- }
-
- if (keyboardMsg) {
- if (implicitLayout)
- xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
- keyboardMsg);
- else
- xf86Msg(X_DEFAULT, "The core keyboard device wasn't specified "
- "explicitly in the layout.\n"
- "\tUsing the %s.\n", keyboardMsg);
- }
-
- if (!xf86Info.forceInputDevices && !(foundPointer && foundKeyboard)) {
-#if defined(CONFIG_HAL) || defined(CONFIG_UDEV)
- const char *config_backend;
-#if defined(CONFIG_HAL)
- config_backend = "HAL";
-#else
- config_backend = "udev";
-#endif
- xf86Msg(X_INFO, "The server relies on %s to provide the list of "
- "input devices.\n\tIf no devices become available, "
- "reconfigure %s or disable AutoAddDevices.\n",
- config_backend, config_backend);
-#else
- xf86Msg(X_WARNING, "Hotplugging requested but the server was "
- "compiled without a config backend. "
- "No input devices were configured, the server "
- "will start without any input devices.\n");
-#endif
- }
-
- return TRUE;
-}
-
-typedef enum {
- LAYOUT_ISOLATEDEVICE,
- LAYOUT_SINGLECARD
-} LayoutValues;
-
-static OptionInfoRec LayoutOptions[] = {
- { LAYOUT_ISOLATEDEVICE, "IsolateDevice", OPTV_STRING,
- {0}, FALSE },
- { LAYOUT_SINGLECARD, "SingleCard", OPTV_BOOLEAN,
- {0}, FALSE },
- { -1, NULL, OPTV_NONE,
- {0}, FALSE },
-};
-
-static Bool
-configInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp)
-{
- XF86ConfInputrefPtr irp;
- InputInfoPtr *indp;
- int count = 0;
-
- /*
- * Count the number of input devices.
- */
- irp = layout->lay_input_lst;
- while (irp) {
- count++;
- irp = (XF86ConfInputrefPtr)irp->list.next;
- }
- DebugF("Found %d input devices in the layout section %s\n",
- count, layout->lay_identifier);
- indp = xnfcalloc((count + 1), sizeof(InputInfoPtr));
- indp[count] = NULL;
- irp = layout->lay_input_lst;
- count = 0;
- while (irp) {
- indp[count] = xf86AllocateInput();
- if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) {
- do {
- free(indp[count]);
- } while(count--);
- free(indp);
- return FALSE;
- }
- indp[count]->options = xf86OptionListMerge(indp[count]->options,
- irp->iref_option_lst);
- count++;
- irp = (XF86ConfInputrefPtr)irp->list.next;
- }
- servlayoutp->inputs = indp;
-
- return TRUE;
-}
-
-
-/*
- * figure out which layout is active, which screens are used in that layout,
- * which drivers and monitors are used in these screens
- */
-static Bool
-configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
- char *default_layout)
-{
- XF86ConfAdjacencyPtr adjp;
- XF86ConfInactivePtr idp;
- int saved_count, count = 0;
- int scrnum;
- XF86ConfLayoutPtr l;
- MessageType from;
- screenLayoutPtr slp;
- GDevPtr gdp;
- int i = 0, j;
-
- if (!servlayoutp)
- return FALSE;
-
- /*
- * which layout section is the active one?
- *
- * If there is a -layout command line option, use that one, otherwise
- * pick the first one.
- */
- from = X_DEFAULT;
- if (xf86LayoutName != NULL)
- from = X_CMDLINE;
- else if (default_layout) {
- xf86LayoutName = default_layout;
- from = X_CONFIG;
- }
- if (xf86LayoutName != NULL) {
- if ((l = xf86findLayout(xf86LayoutName, conf_layout)) == NULL) {
- xf86Msg(X_ERROR, "No ServerLayout section called \"%s\"\n",
- xf86LayoutName);
- return FALSE;
- }
- conf_layout = l;
- }
- xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier);
- adjp = conf_layout->lay_adjacency_lst;
-
- /*
- * we know that each screen is referenced exactly once on the left side
- * of a layout statement in the Layout section. So to allocate the right
- * size for the array we do a quick walk of the list to figure out how
- * many sections we have
- */
- while (adjp) {
- count++;
- adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
- }
-
- DebugF("Found %d screens in the layout section %s",
- count, conf_layout->lay_identifier);
- if (!count) /* alloc enough storage even if no screen is specified */
- count = 1;
-
- slp = xnfcalloc(1, (count + 1) * sizeof(screenLayoutRec));
- slp[count].screen = NULL;
- /*
- * now that we have storage, loop over the list again and fill in our
- * data structure; at this point we do not fill in the adjacency
- * information as it is not clear if we need it at all
- */
- adjp = conf_layout->lay_adjacency_lst;
- count = 0;
- while (adjp) {
- slp[count].screen = xnfcalloc(1, sizeof(confScreenRec));
- if (adjp->adj_scrnum < 0)
- scrnum = count;
- else
- scrnum = adjp->adj_scrnum;
- if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum,
- X_CONFIG)) {
- do {
- free(slp[count].screen);
- } while(count--);
- free(slp);
- return FALSE;
- }
- slp[count].x = adjp->adj_x;
- slp[count].y = adjp->adj_y;
- slp[count].refname = adjp->adj_refscreen;
- switch (adjp->adj_where) {
- case CONF_ADJ_OBSOLETE:
- slp[count].where = PosObsolete;
- slp[count].topname = adjp->adj_top_str;
- slp[count].bottomname = adjp->adj_bottom_str;
- slp[count].leftname = adjp->adj_left_str;
- slp[count].rightname = adjp->adj_right_str;
- break;
- case CONF_ADJ_ABSOLUTE:
- slp[count].where = PosAbsolute;
- break;
- case CONF_ADJ_RIGHTOF:
- slp[count].where = PosRightOf;
- break;
- case CONF_ADJ_LEFTOF:
- slp[count].where = PosLeftOf;
- break;
- case CONF_ADJ_ABOVE:
- slp[count].where = PosAbove;
- break;
- case CONF_ADJ_BELOW:
- slp[count].where = PosBelow;
- break;
- case CONF_ADJ_RELATIVE:
- slp[count].where = PosRelative;
- break;
- }
- count++;
- adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
- }
-
- /* No screen was specified in the layout. take the first one from the
- * config file, or - if it is NULL - configScreen autogenerates one for
- * us */
- if (!count)
- {
- slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
- if (!configScreen(slp[0].screen, xf86configptr->conf_screen_lst,
- 0, X_CONFIG)) {
- free(slp[0].screen);
- free(slp);
- return FALSE;
- }
- }
-
- /* XXX Need to tie down the upper left screen. */
-
- /* Fill in the refscreen and top/bottom/left/right values */
- for (i = 0; i < count; i++) {
- for (j = 0; j < count; j++) {
- if (slp[i].refname &&
- strcmp(slp[i].refname, slp[j].screen->id) == 0) {
- slp[i].refscreen = slp[j].screen;
- }
- if (slp[i].topname &&
- strcmp(slp[i].topname, slp[j].screen->id) == 0) {
- slp[i].top = slp[j].screen;
- }
- if (slp[i].bottomname &&
- strcmp(slp[i].bottomname, slp[j].screen->id) == 0) {
- slp[i].bottom = slp[j].screen;
- }
- if (slp[i].leftname &&
- strcmp(slp[i].leftname, slp[j].screen->id) == 0) {
- slp[i].left = slp[j].screen;
- }
- if (slp[i].rightname &&
- strcmp(slp[i].rightname, slp[j].screen->id) == 0) {
- slp[i].right = slp[j].screen;
- }
- }
- if (slp[i].where != PosObsolete
- && slp[i].where != PosAbsolute
- && !slp[i].refscreen) {
- xf86Msg(X_ERROR,"Screen %s doesn't exist: deleting placement\n",
- slp[i].refname);
- slp[i].where = PosAbsolute;
- slp[i].x = 0;
- slp[i].y = 0;
- }
- }
-
- if (!count)
- saved_count = 1;
- else
- saved_count = count;
- /*
- * Count the number of inactive devices.
- */
- count = 0;
- idp = conf_layout->lay_inactive_lst;
- while (idp) {
- count++;
- idp = (XF86ConfInactivePtr)idp->list.next;
- }
- DebugF("Found %d inactive devices in the layout section %s\n",
- count, conf_layout->lay_identifier);
- gdp = xnfalloc((count + 1) * sizeof(GDevRec));
- gdp[count].identifier = NULL;
- idp = conf_layout->lay_inactive_lst;
- count = 0;
- while (idp) {
- if (!configDevice(&gdp[count], idp->inactive_device, FALSE))
- goto bail;
- count++;
- idp = (XF86ConfInactivePtr)idp->list.next;
- }
-
- if (!configInputDevices(conf_layout, servlayoutp))
- goto bail;
-
- servlayoutp->id = conf_layout->lay_identifier;
- servlayoutp->screens = slp;
- servlayoutp->inactives = gdp;
- servlayoutp->options = conf_layout->lay_option_lst;
- from = X_DEFAULT;
-
- return TRUE;
-
-bail:
- do {
- free(slp[saved_count].screen);
- } while(saved_count--);
- free(slp);
- free(gdp);
- return FALSE;
-}
-
-/*
- * No layout section, so find the first Screen section and set that up as
- * the only active screen.
- */
-static Bool
-configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
- XF86ConfigPtr xf86configptr)
-{
- MessageType from;
- XF86ConfScreenPtr s;
- screenLayoutPtr slp;
- InputInfoPtr *indp;
- XF86ConfLayoutRec layout;
-
- if (!servlayoutp)
- return FALSE;
-
- /*
- * which screen section is the active one?
- *
- * If there is a -screen option, use that one, otherwise use the first
- * one.
- */
-
- from = X_CONFIG;
- if (xf86ScreenName != NULL) {
- if ((s = xf86findScreen(xf86ScreenName, conf_screen)) == NULL) {
- xf86Msg(X_ERROR, "No Screen section called \"%s\"\n",
- xf86ScreenName);
- return FALSE;
- }
- conf_screen = s;
- from = X_CMDLINE;
- }
-
- /* We have exactly one screen */
-
- slp = xnfcalloc(1, 2 * sizeof(screenLayoutRec));
- slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
- slp[1].screen = NULL;
- if (!configScreen(slp[0].screen, conf_screen, 0, from)) {
- free(slp);
- return FALSE;
- }
- servlayoutp->id = "(implicit)";
- servlayoutp->screens = slp;
- servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec));
- servlayoutp->options = NULL;
-
- memset(&layout, 0, sizeof(layout));
- layout.lay_identifier = servlayoutp->id;
- if (xf86layoutAddInputDevices(xf86configptr, &layout) > 0) {
- if (!configInputDevices(&layout, servlayoutp))
- return FALSE;
- from = X_DEFAULT;
- } else {
- /* Set up an empty input device list, then look for some core devices. */
- indp = xnfalloc(sizeof(InputInfoPtr));
- *indp = NULL;
- servlayoutp->inputs = indp;
- }
-
- return TRUE;
-}
-
-static Bool
-configXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor)
-{
- int count = 0;
- XF86ConfVideoPortPtr conf_port;
-
- xf86Msg(X_CONFIG, "| |-->VideoAdaptor \"%s\"\n",
- conf_adaptor->va_identifier);
- adaptor->identifier = conf_adaptor->va_identifier;
- adaptor->options = conf_adaptor->va_option_lst;
- if (conf_adaptor->va_busid || conf_adaptor->va_driver) {
- xf86Msg(X_CONFIG, "| | Unsupported device type, skipping entry\n");
- return FALSE;
- }
-
- /*
- * figure out how many videoport subsections there are and fill them in
- */
- conf_port = conf_adaptor->va_port_lst;
- while(conf_port) {
- count++;
- conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
- }
- adaptor->ports = xnfalloc((count) * sizeof(confXvPortRec));
- adaptor->numports = count;
- count = 0;
- conf_port = conf_adaptor->va_port_lst;
- while(conf_port) {
- adaptor->ports[count].identifier = conf_port->vp_identifier;
- adaptor->ports[count].options = conf_port->vp_option_lst;
- count++;
- conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
- }
-
- return TRUE;
-}
-
-static Bool
-configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
- MessageType from)
-{
- int count = 0;
- XF86ConfDisplayPtr dispptr;
- XF86ConfAdaptorLinkPtr conf_adaptor;
- Bool defaultMonitor = FALSE;
- XF86ConfScreenRec local_conf_screen;
-
- if (!conf_screen) {
- memset(&local_conf_screen, 0, sizeof(local_conf_screen));
- conf_screen = &local_conf_screen;
- conf_screen->scrn_identifier = "Default Screen Section";
- xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n");
- }
-
- xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
- scrnum);
- /*
- * now we fill in the elements of the screen
- */
- screenp->id = conf_screen->scrn_identifier;
- screenp->screennum = scrnum;
- screenp->defaultdepth = conf_screen->scrn_defaultdepth;
- screenp->defaultbpp = conf_screen->scrn_defaultbpp;
- screenp->defaultfbbpp = conf_screen->scrn_defaultfbbpp;
- screenp->monitor = xnfcalloc(1, sizeof(MonRec));
- /* If no monitor is specified, create a default one. */
- if (!conf_screen->scrn_monitor) {
- XF86ConfMonitorRec defMon;
-
- memset(&defMon, 0, sizeof(defMon));
- defMon.mon_identifier = "<default monitor>";
- if (!configMonitor(screenp->monitor, &defMon))
- return FALSE;
- defaultMonitor = TRUE;
- } else {
- if (!configMonitor(screenp->monitor,conf_screen->scrn_monitor))
- return FALSE;
- }
- /* Configure the device. If there isn't one configured, attach to the
- * first inactive one that we can configure. If there's none that work,
- * set it to NULL so that the section can be autoconfigured later */
- screenp->device = xnfcalloc(1, sizeof(GDevRec));
- if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) {
- conf_screen->scrn_device = xf86configptr->conf_device_lst;
- xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
- "\tUsing the first device section listed.\n", screenp->id);
- }
- if (configDevice(screenp->device,conf_screen->scrn_device, TRUE)) {
- screenp->device->myScreenSection = screenp;
- } else {
- screenp->device = NULL;
- }
- screenp->options = conf_screen->scrn_option_lst;
-
- /*
- * figure out how many display subsections there are and fill them in
- */
- dispptr = conf_screen->scrn_display_lst;
- while(dispptr) {
- count++;
- dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
- }
- screenp->displays = xnfalloc((count) * sizeof(DispRec));
- screenp->numdisplays = count;
-
- /* Fill in the default Virtual size, if any */
- if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) {
- for (count = 0, dispptr = conf_screen->scrn_display_lst;
- dispptr;
- dispptr = (XF86ConfDisplayPtr)dispptr->list.next, count++) {
- screenp->displays[count].virtualX = conf_screen->scrn_virtualX;
- screenp->displays[count].virtualY = conf_screen->scrn_virtualY;
- }
- }
-
- /* Now do the per-Display Virtual sizes */
- count = 0;
- dispptr = conf_screen->scrn_display_lst;
- while(dispptr) {
- configDisplay(&(screenp->displays[count]),dispptr);
- count++;
- dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
- }
-
- /*
- * figure out how many videoadaptor references there are and fill them in
- */
- conf_adaptor = conf_screen->scrn_adaptor_lst;
- while(conf_adaptor) {
- count++;
- conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
- }
- screenp->xvadaptors = xnfalloc((count) * sizeof(confXvAdaptorRec));
- screenp->numxvadaptors = 0;
- conf_adaptor = conf_screen->scrn_adaptor_lst;
- while(conf_adaptor) {
- if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]),
- conf_adaptor->al_adaptor))
- screenp->numxvadaptors++;
- conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
- }
-
- if (defaultMonitor) {
- xf86Msg(X_DEFAULT, "No monitor specified for screen \"%s\".\n"
- "\tUsing a default monitor configuration.\n", screenp->id);
- }
- return TRUE;
-}
-
-typedef enum {
- MON_REDUCEDBLANKING,
- MON_MAX_PIX_CLOCK,
-} MonitorValues;
-
-static OptionInfoRec MonitorOptions[] = {
- { MON_REDUCEDBLANKING, "ReducedBlanking", OPTV_BOOLEAN,
- {0}, FALSE },
- { MON_MAX_PIX_CLOCK, "MaxPixClock", OPTV_FREQ,
- {0}, FALSE },
- { -1, NULL, OPTV_NONE,
- {0}, FALSE },
-};
-
-static Bool
-configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor)
-{
- int count;
- DisplayModePtr mode,last = NULL;
- XF86ConfModeLinePtr cmodep;
- XF86ConfModesPtr modes;
- XF86ConfModesLinkPtr modeslnk = conf_monitor->mon_modes_sect_lst;
- Gamma zeros = {0.0, 0.0, 0.0};
- float badgamma = 0.0;
- double maxPixClock;
-
- xf86Msg(X_CONFIG, "| |-->Monitor \"%s\"\n",
- conf_monitor->mon_identifier);
- monitorp->id = conf_monitor->mon_identifier;
- monitorp->vendor = conf_monitor->mon_vendor;
- monitorp->model = conf_monitor->mon_modelname;
- monitorp->Modes = NULL;
- monitorp->Last = NULL;
- monitorp->gamma = zeros;
- monitorp->widthmm = conf_monitor->mon_width;
- monitorp->heightmm = conf_monitor->mon_height;
- monitorp->reducedblanking = FALSE;
- monitorp->maxPixClock = 0;
- monitorp->options = conf_monitor->mon_option_lst;
-
- /*
- * fill in the monitor structure
- */
- for( count = 0 ;
- count < conf_monitor->mon_n_hsync && count < MAX_HSYNC;
- count++) {
- monitorp->hsync[count].hi = conf_monitor->mon_hsync[count].hi;
- monitorp->hsync[count].lo = conf_monitor->mon_hsync[count].lo;
- }
- monitorp->nHsync = count;
- for( count = 0 ;
- count < conf_monitor->mon_n_vrefresh && count < MAX_VREFRESH;
- count++) {
- monitorp->vrefresh[count].hi = conf_monitor->mon_vrefresh[count].hi;
- monitorp->vrefresh[count].lo = conf_monitor->mon_vrefresh[count].lo;
- }
- monitorp->nVrefresh = count;
-
- /*
- * first we collect the mode lines from the UseModes directive
- */
- while(modeslnk)
- {
- modes = xf86findModes (modeslnk->ml_modes_str,
- xf86configptr->conf_modes_lst);
- modeslnk->ml_modes = modes;
-
-
- /* now add the modes found in the modes
- section to the list of modes for this
- monitor unless it has been added before
- because we are reusing the same section
- for another screen */
- if (xf86itemNotSublist(
- (GenericListPtr)conf_monitor->mon_modeline_lst,
- (GenericListPtr)modes->mon_modeline_lst)) {
- conf_monitor->mon_modeline_lst = (XF86ConfModeLinePtr)
- xf86addListItem(
- (GenericListPtr)conf_monitor->mon_modeline_lst,
- (GenericListPtr)modes->mon_modeline_lst);
- }
- modeslnk = modeslnk->list.next;
- }
-
- /*
- * we need to hook in the mode lines now
- * here both data structures use lists, only our internal one
- * is double linked
- */
- cmodep = conf_monitor->mon_modeline_lst;
- while( cmodep ) {
- mode = xnfcalloc(1, sizeof(DisplayModeRec));
- mode->type = 0;
- mode->Clock = cmodep->ml_clock;
- mode->HDisplay = cmodep->ml_hdisplay;
- mode->HSyncStart = cmodep->ml_hsyncstart;
- mode->HSyncEnd = cmodep->ml_hsyncend;
- mode->HTotal = cmodep->ml_htotal;
- mode->VDisplay = cmodep->ml_vdisplay;
- mode->VSyncStart = cmodep->ml_vsyncstart;
- mode->VSyncEnd = cmodep->ml_vsyncend;
- mode->VTotal = cmodep->ml_vtotal;
- mode->Flags = cmodep->ml_flags;
- mode->HSkew = cmodep->ml_hskew;
- mode->VScan = cmodep->ml_vscan;
- mode->name = xnfstrdup(cmodep->ml_identifier);
- if( last ) {
- mode->prev = last;
- last->next = mode;
- }
- else {
- /*
- * this is the first mode
- */
- monitorp->Modes = mode;
- mode->prev = NULL;
- }
- last = mode;
- cmodep = (XF86ConfModeLinePtr)cmodep->list.next;
- }
- if(last){
- last->next = NULL;
- }
- monitorp->Last = last;
-
- /* add the (VESA) default modes */
- if (! addDefaultModes(monitorp) )
- return FALSE;
-
- if (conf_monitor->mon_gamma_red > GAMMA_ZERO)
- monitorp->gamma.red = conf_monitor->mon_gamma_red;
- if (conf_monitor->mon_gamma_green > GAMMA_ZERO)
- monitorp->gamma.green = conf_monitor->mon_gamma_green;
- if (conf_monitor->mon_gamma_blue > GAMMA_ZERO)
- monitorp->gamma.blue = conf_monitor->mon_gamma_blue;
-
- /* Check that the gamma values are within range */
- if (monitorp->gamma.red > GAMMA_ZERO &&
- (monitorp->gamma.red < GAMMA_MIN ||
- monitorp->gamma.red > GAMMA_MAX)) {
- badgamma = monitorp->gamma.red;
- } else if (monitorp->gamma.green > GAMMA_ZERO &&
- (monitorp->gamma.green < GAMMA_MIN ||
- monitorp->gamma.green > GAMMA_MAX)) {
- badgamma = monitorp->gamma.green;
- } else if (monitorp->gamma.blue > GAMMA_ZERO &&
- (monitorp->gamma.blue < GAMMA_MIN ||
- monitorp->gamma.blue > GAMMA_MAX)) {
- badgamma = monitorp->gamma.blue;
- }
- if (badgamma > GAMMA_ZERO) {
- xf86ConfigError("Gamma value %.f is out of range (%.2f - %.1f)\n",
- badgamma, GAMMA_MIN, GAMMA_MAX);
- return FALSE;
- }
-
- xf86ProcessOptions(-1, monitorp->options, MonitorOptions);
- xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING,
- &monitorp->reducedblanking);
- if (xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ,
- &maxPixClock) == TRUE) {
- monitorp->maxPixClock = (int) maxPixClock;
- }
-
- return TRUE;
-}
-
-static int
-lookupVisual(const char *visname)
-{
- int i;
-
- if (!visname || !*visname)
- return -1;
-
- for (i = 0; i <= DirectColor; i++) {
- if (!xf86nameCompare(visname, xf86VisualNames[i]))
- break;
- }
-
- if (i <= DirectColor)
- return i;
-
- return -1;
-}
-
-
-static Bool
-configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
-{
- int count = 0;
- XF86ModePtr modep;
-
- displayp->frameX0 = conf_display->disp_frameX0;
- displayp->frameY0 = conf_display->disp_frameY0;
- displayp->virtualX = conf_display->disp_virtualX;
- displayp->virtualY = conf_display->disp_virtualY;
- displayp->depth = conf_display->disp_depth;
- displayp->fbbpp = conf_display->disp_bpp;
- displayp->weight.red = conf_display->disp_weight.red;
- displayp->weight.green = conf_display->disp_weight.green;
- displayp->weight.blue = conf_display->disp_weight.blue;
- displayp->blackColour.red = conf_display->disp_black.red;
- displayp->blackColour.green = conf_display->disp_black.green;
- displayp->blackColour.blue = conf_display->disp_black.blue;
- displayp->whiteColour.red = conf_display->disp_white.red;
- displayp->whiteColour.green = conf_display->disp_white.green;
- displayp->whiteColour.blue = conf_display->disp_white.blue;
- displayp->options = conf_display->disp_option_lst;
- if (conf_display->disp_visual) {
- displayp->defaultVisual = lookupVisual(conf_display->disp_visual);
- if (displayp->defaultVisual == -1) {
- xf86ConfigError("Invalid visual name: \"%s\"",
- conf_display->disp_visual);
- return FALSE;
- }
- } else {
- displayp->defaultVisual = -1;
- }
-
- /*
- * now hook in the modes
- */
- modep = conf_display->disp_mode_lst;
- while(modep) {
- count++;
- modep = (XF86ModePtr)modep->list.next;
- }
- displayp->modes = xnfalloc((count+1) * sizeof(char*));
- modep = conf_display->disp_mode_lst;
- count = 0;
- while(modep) {
- displayp->modes[count] = modep->mode_name;
- count++;
- modep = (XF86ModePtr)modep->list.next;
- }
- displayp->modes[count] = NULL;
-
- return TRUE;
-}
-
-static Bool
-configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
-{
- int i;
-
- if (!conf_device) {
- return FALSE;
- }
-
- if (active)
- xf86Msg(X_CONFIG, "| |-->Device \"%s\"\n",
- conf_device->dev_identifier);
- else
- xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
- conf_device->dev_identifier);
-
- devicep->identifier = conf_device->dev_identifier;
- devicep->vendor = conf_device->dev_vendor;
- devicep->board = conf_device->dev_board;
- devicep->chipset = conf_device->dev_chipset;
- devicep->ramdac = conf_device->dev_ramdac;
- devicep->driver = conf_device->dev_driver;
- devicep->active = active;
- devicep->videoRam = conf_device->dev_videoram;
- devicep->BiosBase = conf_device->dev_bios_base;
- devicep->MemBase = conf_device->dev_mem_base;
- devicep->IOBase = conf_device->dev_io_base;
- devicep->clockchip = conf_device->dev_clockchip;
- devicep->busID = conf_device->dev_busid;
- devicep->textClockFreq = conf_device->dev_textclockfreq;
- devicep->chipID = conf_device->dev_chipid;
- devicep->chipRev = conf_device->dev_chiprev;
- devicep->options = conf_device->dev_option_lst;
- devicep->irq = conf_device->dev_irq;
- devicep->screen = conf_device->dev_screen;
-
- for (i = 0; i < MAXDACSPEEDS; i++) {
- if (i < CONF_MAXDACSPEEDS)
- devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i];
- else
- devicep->dacSpeeds[i] = 0;
- }
- devicep->numclocks = conf_device->dev_clocks;
- if (devicep->numclocks > MAXCLOCKS)
- devicep->numclocks = MAXCLOCKS;
- for (i = 0; i < devicep->numclocks; i++) {
- devicep->clock[i] = conf_device->dev_clock[i];
- }
- devicep->claimed = FALSE;
-
- return TRUE;
-}
-
-#ifdef XF86DRI
-static void
-configDRI(XF86ConfDRIPtr drip)
-{
- struct group *grp;
-
- xf86ConfigDRI.group = -1;
- xf86ConfigDRI.mode = 0;
-
- if (drip) {
- if (drip->dri_group_name) {
- if ((grp = getgrnam(drip->dri_group_name)))
- xf86ConfigDRI.group = grp->gr_gid;
- } else {
- if (drip->dri_group >= 0)
- xf86ConfigDRI.group = drip->dri_group;
- }
- xf86ConfigDRI.mode = drip->dri_mode;
- }
-}
-#endif
-
-static void
-configExtensions(XF86ConfExtensionsPtr conf_ext)
-{
- XF86OptionPtr o;
-
- if (conf_ext && conf_ext->ext_option_lst) {
- for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) {
- char *name = xf86OptionName(o);
- char *val = xf86OptionValue(o);
- char *n;
- Bool enable = TRUE;
-
- /* Handle "No<ExtensionName>" */
- n = xf86NormalizeName(name);
- if (strncmp(n, "no", 2) == 0) {
- name += 2;
- enable = FALSE;
- }
-
- if (!val ||
- xf86NameCmp(val, "enable") == 0 ||
- xf86NameCmp(val, "enabled") == 0 ||
- xf86NameCmp(val, "on") == 0 ||
- xf86NameCmp(val, "1") == 0 ||
- xf86NameCmp(val, "yes") == 0 ||
- xf86NameCmp(val, "true") == 0) {
- /* NOTHING NEEDED -- enabling is handled below */
- } else if (xf86NameCmp(val, "disable") == 0 ||
- xf86NameCmp(val, "disabled") == 0 ||
- xf86NameCmp(val, "off") == 0 ||
- xf86NameCmp(val, "0") == 0 ||
- xf86NameCmp(val, "no") == 0 ||
- xf86NameCmp(val, "false") == 0) {
- enable = !enable;
- } else {
- xf86Msg(X_WARNING, "Ignoring unrecognized value \"%s\"\n", val);
- free(n);
- continue;
- }
-
- if (EnableDisableExtension(name, enable)) {
- xf86Msg(X_CONFIG, "Extension \"%s\" is %s\n",
- name, enable ? "enabled" : "disabled");
- } else {
- xf86Msg(X_WARNING, "Ignoring unrecognized extension \"%s\"\n",
- name);
- }
- free(n);
- }
- }
-}
-
-static Bool
-configInput(InputInfoPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
-{
- xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier);
- inputp->name = conf_input->inp_identifier;
- inputp->driver = conf_input->inp_driver;
- inputp->options = conf_input->inp_option_lst;
- inputp->attrs = NULL;
-
- return TRUE;
-}
-
-static Bool
-modeIsPresent(DisplayModePtr mode, MonPtr monitorp)
-{
- DisplayModePtr knownmodes = monitorp->Modes;
-
- /* all I can think of is a linear search... */
- while(knownmodes != NULL)
- {
- if(!strcmp(mode->name, knownmodes->name) &&
- !(knownmodes->type & M_T_DEFAULT))
- return TRUE;
- knownmodes = knownmodes->next;
- }
- return FALSE;
-}
-
-static Bool
-addDefaultModes(MonPtr monitorp)
-{
- DisplayModePtr mode;
- DisplayModePtr last = monitorp->Last;
- int i = 0;
-
- for (i = 0; i < xf86NumDefaultModes; i++)
- {
- mode = xf86DuplicateMode(&xf86DefaultModes[i]);
- if (!modeIsPresent(mode, monitorp))
- {
- monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode);
- last = mode;
- } else {
- free(mode);
- }
- }
- monitorp->Last = last;
-
- return TRUE;
-}
-
-static void
-checkInput(serverLayoutPtr layout, Bool implicit_layout) {
- checkCoreInputDevices(layout, implicit_layout);
-
- /* Unless we're forcing input devices, disable mouse/kbd devices in the
- * config. Otherwise the same physical device is added multiple times,
- * leading to duplicate events.
- */
- if (!xf86Info.forceInputDevices && layout->inputs)
- {
- InputInfoPtr *dev = layout->inputs;
- BOOL warned = FALSE;
-
- while(*dev)
- {
- if (strcmp((*dev)->driver, "kbd") == 0 ||
- strcmp((*dev)->driver, "mouse") == 0 ||
- strcmp((*dev)->driver, "vmmouse") == 0)
- {
- InputInfoPtr *current;
- if (!warned)
- {
- xf86Msg(X_WARNING, "Hotplugging is on, devices using "
- "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n");
- warned = TRUE;
- }
-
- xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->name);
-
- current = dev;
- free(*dev);
-
- do {
- *current = *(current + 1);
- current++;
- } while(*current);
- } else
- dev++;
- }
- }
-}
-
-/*
- * load the config file and fill the global data structure
- */
-ConfigStatus
-xf86HandleConfigFile(Bool autoconfig)
-{
- const char *filename, *dirname, *sysdirname;
- char *filesearch, *dirsearch;
- MessageType filefrom = X_DEFAULT;
- MessageType dirfrom = X_DEFAULT;
- char *scanptr;
- Bool singlecard = 0;
- Bool implicit_layout = FALSE;
-
- if (!autoconfig) {
- if (getuid() == 0) {
- filesearch = ROOT_CONFIGPATH;
- dirsearch = ROOT_CONFIGDIRPATH;
- } else {
- filesearch = USER_CONFIGPATH;
- dirsearch = USER_CONFIGDIRPATH;
- }
-
- if (xf86ConfigFile)
- filefrom = X_CMDLINE;
- if (xf86ConfigDir)
- dirfrom = X_CMDLINE;
-
- xf86initConfigFiles();
- sysdirname = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL,
- PROJECTROOT);
- dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT);
- filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT);
- if (filename) {
- xf86MsgVerb(filefrom, 0, "Using config file: \"%s\"\n", filename);
- xf86ConfigFile = xnfstrdup(filename);
- } else {
- if (xf86ConfigFile)
- xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
- xf86ConfigFile);
- }
- if (dirname) {
- xf86MsgVerb(dirfrom, 0, "Using config directory: \"%s\"\n",
- dirname);
- xf86ConfigDir = xnfstrdup(dirname);
- } else {
- if (xf86ConfigDir)
- xf86Msg(X_ERROR,
- "Unable to locate/open config directory: \"%s\"\n",
- xf86ConfigDir);
- }
- if (sysdirname)
- xf86MsgVerb(X_DEFAULT, 0, "Using system config directory \"%s\"\n",
- sysdirname);
- if (!filename && !dirname && !sysdirname)
- return CONFIG_NOFILE;
- }
-
- if ((xf86configptr = xf86readConfigFile ()) == NULL) {
- xf86Msg(X_ERROR, "Problem parsing the config file\n");
- return CONFIG_PARSE_ERROR;
- }
- xf86closeConfigFile ();
-
- /* Initialise a few things. */
-
- /*
- * now we convert part of the information contained in the parser
- * structures into our own structures.
- * The important part here is to figure out which Screen Sections
- * in the XF86Config file are active so that we can piece together
- * the modes that we need later down the road.
- * And while we are at it, we'll decode the rest of the stuff as well
- */
-
- /* First check if a layout section is present, and if it is valid. */
-
- if (xf86configptr->conf_layout_lst == NULL || xf86ScreenName != NULL) {
- if (xf86ScreenName == NULL) {
- xf86Msg(X_DEFAULT,
- "No Layout section. Using the first Screen section.\n");
- }
- if (!configImpliedLayout(&xf86ConfigLayout,
- xf86configptr->conf_screen_lst,
- xf86configptr)) {
- xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
- return CONFIG_PARSE_ERROR;
- }
- implicit_layout = TRUE;
- } else {
- if (xf86configptr->conf_flags != NULL) {
- char *dfltlayout = NULL;
- pointer optlist = xf86configptr->conf_flags->flg_option_lst;
-
- if (optlist && xf86FindOption(optlist, "defaultserverlayout"))
- dfltlayout = xf86SetStrOption(optlist, "defaultserverlayout", NULL);
- if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
- dfltlayout)) {
- xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
- return CONFIG_PARSE_ERROR;
- }
- } else {
- if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
- NULL)) {
- xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
- return CONFIG_PARSE_ERROR;
- }
- }
- }
-
- xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions);
-
- if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) {
- ; /* IsolateDevice specified; overrides SingleCard */
- } else {
- xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard);
- if (singlecard)
- scanptr = xf86ConfigLayout.screens->screen->device->busID;
- }
- if (scanptr) {
- if (strncmp(scanptr, "PCI:", 4) != 0) {
- xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n"
- "\tIgnoring IsolateDevice option.\n");
- } else
- xf86PciIsolateDevice(scanptr);
- }
-
- /* Now process everything else */
- if (!configServerFlags(xf86configptr->conf_flags,xf86ConfigLayout.options)){
- ErrorF ("Problem when converting the config data structures\n");
- return CONFIG_PARSE_ERROR;
- }
-
- configFiles(xf86configptr->conf_files);
- configExtensions(xf86configptr->conf_extensions);
-#ifdef XF86DRI
- configDRI(xf86configptr->conf_dri);
-#endif
-
- checkInput(&xf86ConfigLayout, implicit_layout);
-
- /*
- * Handle some command line options that can override some of the
- * ServerFlags settings.
- */
-#ifdef XF86VIDMODE
- if (xf86VidModeDisabled)
- xf86Info.vidModeEnabled = FALSE;
- if (xf86VidModeAllowNonLocal)
- xf86Info.vidModeAllowNonLocal = TRUE;
-#endif
-
- if (xf86AllowMouseOpenFail)
- xf86Info.allowMouseOpenFail = TRUE;
-
- return CONFIG_OK;
-}
-
-Bool
-xf86PathIsSafe(const char *path)
-{
- return (xf86pathIsSafe(path) != 0);
-}
+/*
+ * Loosely based on code bearing the following copyright:
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ */
+
+/*
+ * Copyright 1992-2003 by The XFree86 Project, Inc.
+ * Copyright 1997 by Metro Link, 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).
+ */
+
+/*
+ *
+ * Authors:
+ * Dirk Hohndel <hohndel@XFree86.Org>
+ * David Dawes <dawes@XFree86.Org>
+ * Marc La France <tsi@XFree86.Org>
+ * Egbert Eich <eich@XFree86.Org>
+ * ... and others
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#ifdef XF86DRI
+#include <sys/types.h>
+#include <grp.h>
+#endif
+
+#include "xf86.h"
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "xf86Config.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "configProcs.h"
+#include "globals.h"
+#include "extension.h"
+#include "xf86pciBus.h"
+
+#include "xf86Xinput.h"
+
+#include "xkbsrv.h"
+
+#include "picture.h"
+
+/*
+ * These paths define the way the config file search is done. The escape
+ * sequences are documented in parser/scan.c.
+ */
+#ifndef ROOT_CONFIGPATH
+#define ROOT_CONFIGPATH "%A," "%R," \
+ "/etc/X11/%R," "%P/etc/X11/%R," \
+ "%E," "%F," \
+ "/etc/X11/%F," "%P/etc/X11/%F," \
+ "/etc/X11/%X," "/etc/%X," \
+ "%P/etc/X11/%X.%H," \
+ "%P/etc/X11/%X," \
+ "%P/lib/X11/%X.%H," \
+ "%P/lib/X11/%X"
+#endif
+#ifndef USER_CONFIGPATH
+#define USER_CONFIGPATH "/etc/X11/%S," "%P/etc/X11/%S," \
+ "/etc/X11/%G," "%P/etc/X11/%G," \
+ "/etc/X11/%X," "/etc/%X," \
+ "%P/etc/X11/%X.%H," \
+ "%P/etc/X11/%X," \
+ "%P/lib/X11/%X.%H," \
+ "%P/lib/X11/%X"
+#endif
+#ifndef ROOT_CONFIGDIRPATH
+#define ROOT_CONFIGDIRPATH "%A," "%R," \
+ "/etc/X11/%R," "%C/X11/%R," \
+ "/etc/X11/%X," "%C/X11/%X"
+#endif
+#ifndef USER_CONFIGDIRPATH
+#define USER_CONFIGDIRPATH "/etc/X11/%R," "%C/X11/%R," \
+ "/etc/X11/%X," "%C/X11/%X"
+#endif
+#ifndef SYS_CONFIGDIRPATH
+#define SYS_CONFIGDIRPATH "/usr/share/X11/%X," "%D/X11/%X"
+#endif
+#ifndef PROJECTROOT
+#define PROJECTROOT "/usr/X11R6"
+#endif
+
+static ModuleDefault ModuleDefaults[] = {
+ {.name = "extmod", .toLoad = TRUE, .load_opt=NULL},
+#ifdef DBE
+ {.name = "dbe", .toLoad = TRUE, .load_opt=NULL},
+#endif
+#ifdef GLXEXT
+ {.name = "glx", .toLoad = TRUE, .load_opt=NULL},
+#endif
+#ifdef XRECORD
+ {.name = "record", .toLoad = TRUE, .load_opt=NULL},
+#endif
+#ifdef XF86DRI
+ {.name = "dri", .toLoad = TRUE, .load_opt=NULL},
+#endif
+#ifdef DRI2
+ {.name = "dri2", .toLoad = TRUE, .load_opt=NULL},
+#endif
+ {.name = NULL, .toLoad = FALSE, .load_opt=NULL}
+};
+
+
+/* Forward declarations */
+static Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen,
+ int scrnum, MessageType from);
+static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor);
+static Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device,
+ Bool active);
+static Bool configInput(InputInfoPtr pInfo, XF86ConfInputPtr conf_input,
+ MessageType from);
+static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display);
+static Bool addDefaultModes(MonPtr monitorp);
+#ifdef XF86DRI
+static void configDRI(XF86ConfDRIPtr drip);
+#endif
+static void configExtensions(XF86ConfExtensionsPtr conf_ext);
+
+/*
+ * xf86GetPathElem --
+ * Extract a single element from the font path string starting at
+ * pnt. The font path element will be returned, and pnt will be
+ * updated to point to the start of the next element, or set to
+ * NULL if there are no more.
+ */
+static char *
+xf86GetPathElem(char **pnt)
+{
+ char *p1;
+
+ p1 = *pnt;
+ *pnt = index(*pnt, ',');
+ if (*pnt != NULL) {
+ **pnt = '\0';
+ *pnt += 1;
+ }
+ return p1;
+}
+
+/*
+ * xf86ValidateFontPath --
+ * Validates the user-specified font path. Each element that
+ * begins with a '/' is checked to make sure the directory exists.
+ * If the directory exists, the existence of a file named 'fonts.dir'
+ * is checked. If either check fails, an error is printed and the
+ * element is removed from the font path.
+ */
+
+#define DIR_FILE "/fonts.dir"
+static char *
+xf86ValidateFontPath(char *path)
+{
+ char *tmp_path, *out_pnt, *path_elem, *next, *p1, *dir_elem;
+ struct stat stat_buf;
+ int flag;
+ int dirlen;
+
+ tmp_path = calloc(1,strlen(path)+1);
+ out_pnt = tmp_path;
+ path_elem = NULL;
+ next = path;
+ while (next != NULL) {
+ path_elem = xf86GetPathElem(&next);
+ if (*path_elem == '/') {
+ dir_elem = xnfcalloc(1, strlen(path_elem) + 1);
+ if ((p1 = strchr(path_elem, ':')) != 0)
+ dirlen = p1 - path_elem;
+ else
+ dirlen = strlen(path_elem);
+ strncpy(dir_elem, path_elem, dirlen);
+ dir_elem[dirlen] = '\0';
+ flag = stat(dir_elem, &stat_buf);
+ if (flag == 0)
+ if (!S_ISDIR(stat_buf.st_mode))
+ flag = -1;
+ if (flag != 0) {
+ xf86Msg(X_WARNING, "The directory \"%s\" does not exist.\n", dir_elem);
+ xf86ErrorF("\tEntry deleted from font path.\n");
+ free(dir_elem);
+ continue;
+ }
+ else {
+ XNFasprintf(&p1, "%s%s", dir_elem, DIR_FILE);
+ flag = stat(p1, &stat_buf);
+ if (flag == 0)
+ if (!S_ISREG(stat_buf.st_mode))
+ flag = -1;
+ free(p1);
+ if (flag != 0) {
+ xf86Msg(X_WARNING,
+ "`fonts.dir' not found (or not valid) in \"%s\".\n",
+ dir_elem);
+ xf86ErrorF("\tEntry deleted from font path.\n");
+ xf86ErrorF("\t(Run 'mkfontdir' on \"%s\").\n", dir_elem);
+ free(dir_elem);
+ continue;
+ }
+ }
+ free(dir_elem);
+ }
+
+ /*
+ * Either an OK directory, or a font server name. So add it to
+ * the path.
+ */
+ if (out_pnt != tmp_path)
+ *out_pnt++ = ',';
+ strcat(out_pnt, path_elem);
+ out_pnt += strlen(path_elem);
+ }
+ return tmp_path;
+}
+
+
+/*
+ * use the datastructure that the parser provides and pick out the parts
+ * that we need at this point
+ */
+char **
+xf86ModulelistFromConfig(pointer **optlist)
+{
+ int count = 0, i = 0;
+ char **modulearray;
+ char *ignore[] = { "GLcore", "speedo", "bitmap", "drm",
+ "freetype", "type1",
+ NULL };
+ pointer *optarray;
+ XF86LoadPtr modp;
+ Bool found;
+
+ /*
+ * make sure the config file has been parsed and that we have a
+ * ModulePath set; if no ModulePath was given, use the default
+ * ModulePath
+ */
+ if (xf86configptr == NULL) {
+ xf86Msg(X_ERROR, "Cannot access global config data structure\n");
+ return NULL;
+ }
+
+ if (xf86configptr->conf_modules) {
+ /* Walk the disable list and let people know what we've parsed to
+ * not be loaded
+ */
+ modp = xf86configptr->conf_modules->mod_disable_lst;
+ while (modp) {
+ xf86Msg(X_WARNING, "\"%s\" will not be loaded unless you've specified it to be loaded elsewhere.\n", modp->load_name);
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+ /*
+ * Walk the default settings table. For each module listed to be
+ * loaded, make sure it's in the mod_load_lst. If it's not, make
+ * sure it's not in the mod_no_load_lst. If it's not disabled,
+ * append it to mod_load_lst
+ */
+ for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
+ if (ModuleDefaults[i].toLoad == FALSE) {
+ xf86Msg(X_WARNING, "\"%s\" is not to be loaded by default. Skipping.\n", ModuleDefaults[i].name);
+ continue;
+ }
+ found = FALSE;
+ modp = xf86configptr->conf_modules->mod_load_lst;
+ while (modp) {
+ if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
+ xf86Msg(X_INFO, "\"%s\" will be loaded. This was enabled by default and also specified in the config file.\n", ModuleDefaults[i].name);
+ found = TRUE;
+ break;
+ }
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+ if (found == FALSE) {
+ modp = xf86configptr->conf_modules->mod_disable_lst;
+ while (modp) {
+ if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
+ xf86Msg(X_INFO, "\"%s\" will be loaded even though the default is to disable it.\n", ModuleDefaults[i].name);
+ found = TRUE;
+ break;
+ }
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+ }
+ if (found == FALSE) {
+ XF86LoadPtr ptr = (XF86LoadPtr)xf86configptr->conf_modules;
+ xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
+ xf86Msg(X_INFO, "\"%s\" will be loaded by default.\n", ModuleDefaults[i].name);
+ }
+ }
+ } else {
+ xf86configptr->conf_modules = xnfcalloc(1, sizeof(XF86ConfModuleRec));
+ for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
+ if (ModuleDefaults[i].toLoad == TRUE) {
+ XF86LoadPtr ptr = (XF86LoadPtr)xf86configptr->conf_modules;
+ xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
+ }
+ }
+ }
+
+ /*
+ * Walk the list of modules in the "Module" section to determine how
+ * many we have.
+ */
+ modp = xf86configptr->conf_modules->mod_load_lst;
+ while (modp) {
+ for (i = 0; ignore[i]; i++) {
+ if (strcmp(modp->load_name, ignore[i]) == 0)
+ modp->ignore = 1;
+ }
+ if (!modp->ignore)
+ count++;
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+
+ /*
+ * allocate the memory and walk the list again to fill in the pointers
+ */
+ modulearray = xnfalloc((count + 1) * sizeof(char*));
+ optarray = xnfalloc((count + 1) * sizeof(pointer));
+ count = 0;
+ if (xf86configptr->conf_modules) {
+ modp = xf86configptr->conf_modules->mod_load_lst;
+ while (modp) {
+ if (!modp->ignore) {
+ modulearray[count] = modp->load_name;
+ optarray[count] = modp->load_opt;
+ count++;
+ }
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+ }
+ modulearray[count] = NULL;
+ optarray[count] = NULL;
+ if (optlist)
+ *optlist = optarray;
+ else
+ free(optarray);
+ return modulearray;
+}
+
+
+char **
+xf86DriverlistFromConfig(void)
+{
+ int count = 0;
+ int j;
+ char **modulearray;
+ screenLayoutPtr slp;
+
+ /*
+ * make sure the config file has been parsed and that we have a
+ * ModulePath set; if no ModulePath was given, use the default
+ * ModulePath
+ */
+ if (xf86configptr == NULL) {
+ xf86Msg(X_ERROR, "Cannot access global config data structure\n");
+ return NULL;
+ }
+
+ /*
+ * Walk the list of driver lines in active "Device" sections to
+ * determine now many implicitly loaded modules there are.
+ *
+ */
+ if (xf86ConfigLayout.screens) {
+ slp = xf86ConfigLayout.screens;
+ while ((slp++)->screen) {
+ count++;
+ }
+ }
+
+ /*
+ * Handle the set of inactive "Device" sections.
+ */
+ j = 0;
+ while (xf86ConfigLayout.inactives[j++].identifier)
+ count++;
+
+ if (count == 0)
+ return NULL;
+
+ /*
+ * allocate the memory and walk the list again to fill in the pointers
+ */
+ modulearray = xnfalloc((count + 1) * sizeof(char*));
+ count = 0;
+ slp = xf86ConfigLayout.screens;
+ while (slp->screen) {
+ modulearray[count] = slp->screen->device->driver;
+ count++;
+ slp++;
+ }
+
+ j = 0;
+
+ while (xf86ConfigLayout.inactives[j].identifier)
+ modulearray[count++] = xf86ConfigLayout.inactives[j++].driver;
+
+ modulearray[count] = NULL;
+
+ /* Remove duplicates */
+ for (count = 0; modulearray[count] != NULL; count++) {
+ int i;
+
+ for (i = 0; i < count; i++)
+ if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
+ modulearray[count] = "";
+ break;
+ }
+ }
+ return modulearray;
+}
+
+char **
+xf86InputDriverlistFromConfig(void)
+{
+ int count = 0;
+ char **modulearray;
+ InputInfoPtr *idp;
+
+ /*
+ * make sure the config file has been parsed and that we have a
+ * ModulePath set; if no ModulePath was given, use the default
+ * ModulePath
+ */
+ if (xf86configptr == NULL) {
+ xf86Msg(X_ERROR, "Cannot access global config data structure\n");
+ return NULL;
+ }
+
+ /*
+ * Walk the list of driver lines in active "InputDevice" sections to
+ * determine now many implicitly loaded modules there are.
+ */
+ if (xf86ConfigLayout.inputs) {
+ idp = xf86ConfigLayout.inputs;
+ while (*idp) {
+ count++;
+ idp++;
+ }
+ }
+
+ if (count == 0)
+ return NULL;
+
+ /*
+ * allocate the memory and walk the list again to fill in the pointers
+ */
+ modulearray = xnfalloc((count + 1) * sizeof(char*));
+ count = 0;
+ idp = xf86ConfigLayout.inputs;
+ while (idp && *idp) {
+ modulearray[count] = (*idp)->driver;
+ count++;
+ idp++;
+ }
+ modulearray[count] = NULL;
+
+ /* Remove duplicates */
+ for (count = 0; modulearray[count] != NULL; count++) {
+ int i;
+
+ for (i = 0; i < count; i++)
+ if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
+ modulearray[count] = "";
+ break;
+ }
+ }
+ return modulearray;
+}
+
+static void
+fixup_video_driver_list(char **drivers)
+{
+ static const char *fallback[4] = { "vesa", "fbdev", "wsfb", NULL };
+ char **end, **drv;
+ char *x;
+ int i;
+
+ /* walk to the end of the list */
+ for (end = drivers; *end && **end; end++) ;
+ end--;
+
+ /*
+ * for each of the fallback drivers, if we find it in the list,
+ * swap it with the last available non-fallback driver.
+ */
+ for (i = 0; fallback[i]; i++) {
+ for (drv = drivers; drv != end; drv++) {
+ if (strstr(*drv, fallback[i])) {
+ x = *drv; *drv = *end; *end = x;
+ end--;
+ break;
+ }
+ }
+ }
+}
+
+static char **
+GenerateDriverlist(char * dirname)
+{
+ char **ret;
+ const char *subdirs[] = { dirname, NULL };
+ static const char *patlist[] = {"(.*)_drv\\.so", NULL};
+ ret = LoaderListDirs(subdirs, patlist);
+
+ /* fix up the probe order for video drivers */
+ if (strstr(dirname, "drivers") && ret != NULL)
+ fixup_video_driver_list(ret);
+
+ return ret;
+}
+
+char **
+xf86DriverlistFromCompile(void)
+{
+ static char **driverlist = NULL;
+
+ if (!driverlist)
+ driverlist = GenerateDriverlist("drivers");
+
+ return driverlist;
+}
+
+/*
+ * xf86ConfigError --
+ * Print a READABLE ErrorMessage!!! All information that is
+ * available is printed.
+ */
+static void
+xf86ConfigError(char *msg, ...)
+{
+ va_list ap;
+
+ ErrorF("\nConfig Error:\n");
+ va_start(ap, msg);
+ VErrorF(msg, ap);
+ va_end(ap);
+ ErrorF("\n");
+ return;
+}
+
+static void
+configFiles(XF86ConfFilesPtr fileconf)
+{
+ MessageType pathFrom;
+ Bool must_copy;
+ int size, countDirs;
+ char *temp_path, *log_buf, *start, *end;
+
+ /* FontPath */
+ must_copy = TRUE;
+
+ temp_path = defaultFontPath ? defaultFontPath : "";
+ if (xf86fpFlag)
+ pathFrom = X_CMDLINE;
+ else if (fileconf && fileconf->file_fontpath) {
+ pathFrom = X_CONFIG;
+ if (xf86Info.useDefaultFontPath) {
+ if (asprintf(&defaultFontPath, "%s%s%s", fileconf->file_fontpath,
+ *temp_path ? "," : "", temp_path) == -1)
+ defaultFontPath = NULL;
+ else
+ must_copy = FALSE;
+ }
+ else
+ defaultFontPath = fileconf->file_fontpath;
+ }
+ else
+ pathFrom = X_DEFAULT;
+ temp_path = defaultFontPath ? defaultFontPath : "";
+
+ /* xf86ValidateFontPath modifies its argument, but returns a copy of it. */
+ temp_path = must_copy ? xnfstrdup(defaultFontPath) : defaultFontPath;
+ defaultFontPath = xf86ValidateFontPath(temp_path);
+ free(temp_path);
+
+ /* make fontpath more readable in the logfiles */
+ countDirs = 1;
+ temp_path = defaultFontPath;
+ while ((temp_path = index(temp_path, ',')) != NULL) {
+ countDirs++;
+ temp_path++;
+ }
+
+ log_buf = xnfalloc(strlen(defaultFontPath) + (2 * countDirs) + 1);
+ temp_path = log_buf;
+ start = defaultFontPath;
+ while((end = index(start, ',')) != NULL) {
+ size = (end - start) + 1;
+ *(temp_path++) = '\t';
+ strncpy(temp_path, start, size);
+ temp_path += size;
+ *(temp_path++) = '\n';
+ start += size;
+ }
+ /* copy last entry */
+ *(temp_path++) = '\t';
+ strcpy(temp_path, start);
+ xf86Msg(pathFrom, "FontPath set to:\n%s\n", log_buf);
+ free(log_buf);
+
+ /* ModulePath */
+
+ if (fileconf) {
+ if (xf86ModPathFrom != X_CMDLINE && fileconf->file_modulepath) {
+ xf86ModulePath = fileconf->file_modulepath;
+ xf86ModPathFrom = X_CONFIG;
+ }
+ }
+
+ xf86Msg(xf86ModPathFrom, "ModulePath set to \"%s\"\n", xf86ModulePath);
+
+ if (!xf86xkbdirFlag && fileconf && fileconf->file_xkbdir) {
+ XkbBaseDirectory = fileconf->file_xkbdir;
+ xf86Msg(X_CONFIG, "XKB base directory set to \"%s\"\n",
+ XkbBaseDirectory);
+ }
+#if 0
+ /* LogFile */
+ /*
+ * XXX The problem with this is that the log file is already open.
+ * One option might be to copy the exiting contents to the new location.
+ * and re-open it. The down side is that the default location would
+ * already have been overwritten. Another option would be to start with
+ * unique temporary location, then copy it once the correct name is known.
+ * A problem with this is what happens if the server exits before that
+ * happens.
+ */
+ if (xf86LogFileFrom == X_DEFAULT && fileconf->file_logfile) {
+ xf86LogFile = fileconf->file_logfile;
+ xf86LogFileFrom = X_CONFIG;
+ }
+#endif
+
+ return;
+}
+
+typedef enum {
+ FLAG_NOTRAPSIGNALS,
+ FLAG_DONTVTSWITCH,
+ FLAG_DONTZAP,
+ FLAG_DONTZOOM,
+ FLAG_DISABLEVIDMODE,
+ FLAG_ALLOWNONLOCAL,
+ FLAG_ALLOWMOUSEOPENFAIL,
+ FLAG_VTSYSREQ,
+ FLAG_SAVER_BLANKTIME,
+ FLAG_DPMS_STANDBYTIME,
+ FLAG_DPMS_SUSPENDTIME,
+ FLAG_DPMS_OFFTIME,
+ FLAG_PIXMAP,
+ FLAG_PC98,
+ FLAG_NOPM,
+ FLAG_XINERAMA,
+ FLAG_LOG,
+ FLAG_RENDER_COLORMAP_MODE,
+ FLAG_RANDR,
+ FLAG_AIGLX,
+ FLAG_IGNORE_ABI,
+ FLAG_ALLOW_EMPTY_INPUT,
+ FLAG_USE_DEFAULT_FONT_PATH,
+ FLAG_AUTO_ADD_DEVICES,
+ FLAG_AUTO_ENABLE_DEVICES,
+ FLAG_GLX_VISUALS,
+ FLAG_DRI2,
+ FLAG_USE_SIGIO
+} FlagValues;
+
+/**
+ * NOTE: the last value for each entry is NOT the default. It is set to TRUE
+ * if the parser found the option in the config file.
+ */
+static OptionInfoRec FlagOptions[] = {
+ { FLAG_NOTRAPSIGNALS, "NoTrapSignals", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_DONTVTSWITCH, "DontVTSwitch", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_DONTZAP, "DontZap", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_DONTZOOM, "DontZoom", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_DISABLEVIDMODE, "DisableVidModeExtension", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_ALLOWNONLOCAL, "AllowNonLocalXvidtune", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_ALLOWMOUSEOPENFAIL, "AllowMouseOpenFail", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_VTSYSREQ, "VTSysReq", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_SAVER_BLANKTIME, "BlankTime" , OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_DPMS_STANDBYTIME, "StandbyTime", OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_DPMS_SUSPENDTIME, "SuspendTime", OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_DPMS_OFFTIME, "OffTime", OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_PIXMAP, "Pixmap", OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_PC98, "PC98", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_NOPM, "NoPM", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_XINERAMA, "Xinerama", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_LOG, "Log", OPTV_STRING,
+ {0}, FALSE },
+ { FLAG_RENDER_COLORMAP_MODE, "RenderColormapMode", OPTV_STRING,
+ {0}, FALSE },
+ { FLAG_RANDR, "RandR", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_AIGLX, "AIGLX", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_IGNORE_ABI, "IgnoreABI", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_USE_DEFAULT_FONT_PATH, "UseDefaultFontPath", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_AUTO_ADD_DEVICES, "AutoAddDevices", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_AUTO_ENABLE_DEVICES, "AutoEnableDevices", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_GLX_VISUALS, "GlxVisuals", OPTV_STRING,
+ {0}, FALSE },
+ { FLAG_DRI2, "DRI2", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_USE_SIGIO, "UseSIGIO", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { -1, NULL, OPTV_NONE,
+ {0}, FALSE },
+};
+
+#ifdef SUPPORT_PC98
+static Bool
+detectPC98(void)
+{
+ unsigned char buf[2];
+
+ if (xf86ReadBIOS(0xf8000, 0xe80, buf, 2) != 2)
+ return FALSE;
+ if ((buf[0] == 0x98) && (buf[1] == 0x21))
+ return TRUE;
+ else
+ return FALSE;
+}
+#endif
+
+static Bool
+configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
+{
+ XF86OptionPtr optp, tmp;
+ int i;
+ Pix24Flags pix24 = Pix24DontCare;
+ Bool value;
+ MessageType from;
+ const char *s;
+ XkbRMLVOSet set;
+ /* Default options. */
+ set.rules = "base";
+ set.model = "pc105";
+ set.layout = "us";
+ set.variant = NULL;
+ set.options = NULL;
+
+ /*
+ * Merge the ServerLayout and ServerFlags options. The former have
+ * precedence over the latter.
+ */
+ optp = NULL;
+ if (flagsconf && flagsconf->flg_option_lst)
+ optp = xf86optionListDup(flagsconf->flg_option_lst);
+ if (layoutopts) {
+ tmp = xf86optionListDup(layoutopts);
+ if (optp)
+ optp = xf86optionListMerge(optp, tmp);
+ else
+ optp = tmp;
+ }
+
+ xf86ProcessOptions(-1, optp, FlagOptions);
+
+ xf86GetOptValBool(FlagOptions, FLAG_NOTRAPSIGNALS, &xf86Info.notrapSignals);
+ xf86GetOptValBool(FlagOptions, FLAG_DONTVTSWITCH, &xf86Info.dontVTSwitch);
+ xf86GetOptValBool(FlagOptions, FLAG_DONTZAP, &xf86Info.dontZap);
+ xf86GetOptValBool(FlagOptions, FLAG_DONTZOOM, &xf86Info.dontZoom);
+
+ xf86GetOptValBool(FlagOptions, FLAG_IGNORE_ABI, &xf86Info.ignoreABI);
+ if (xf86Info.ignoreABI) {
+ xf86Msg(X_CONFIG, "Ignoring ABI Version\n");
+ }
+
+ if (xf86SIGIOSupported()) {
+ xf86Info.useSIGIO = xf86ReturnOptValBool(FlagOptions, FLAG_USE_SIGIO, USE_SIGIO_BY_DEFAULT);
+ if (xf86IsOptionSet(FlagOptions, FLAG_USE_SIGIO)) {
+ from = X_CONFIG;
+ } else {
+ from = X_DEFAULT;
+ }
+ if (!xf86Info.useSIGIO) {
+ xf86Msg(from, "Disabling SIGIO handlers for input devices\n");
+ } else if (from == X_CONFIG) {
+ xf86Msg(from, "Enabling SIGIO handlers for input devices\n");
+ }
+ } else {
+ xf86Info.useSIGIO = FALSE;
+ }
+
+ if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_DEVICES)) {
+ xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_DEVICES,
+ &xf86Info.autoAddDevices);
+ from = X_CONFIG;
+ }
+ else {
+ from = X_DEFAULT;
+ }
+ xf86Msg(from, "%sutomatically adding devices\n",
+ xf86Info.autoAddDevices ? "A" : "Not a");
+
+ if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ENABLE_DEVICES)) {
+ xf86GetOptValBool(FlagOptions, FLAG_AUTO_ENABLE_DEVICES,
+ &xf86Info.autoEnableDevices);
+ from = X_CONFIG;
+ }
+ else {
+ from = X_DEFAULT;
+ }
+ xf86Msg(from, "%sutomatically enabling devices\n",
+ xf86Info.autoEnableDevices ? "A" : "Not a");
+
+ /*
+ * Set things up based on the config file information. Some of these
+ * settings may be overridden later when the command line options are
+ * checked.
+ */
+#ifdef XF86VIDMODE
+ if (xf86GetOptValBool(FlagOptions, FLAG_DISABLEVIDMODE, &value))
+ xf86Info.vidModeEnabled = !value;
+ if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWNONLOCAL, &value))
+ xf86Info.vidModeAllowNonLocal = value;
+#endif
+
+ if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWMOUSEOPENFAIL, &value))
+ xf86Info.allowMouseOpenFail = value;
+
+ if (xf86GetOptValBool(FlagOptions, FLAG_VTSYSREQ, &value)) {
+#ifdef USE_VT_SYSREQ
+ xf86Info.vtSysreq = value;
+ xf86Msg(X_CONFIG, "VTSysReq %s\n", value ? "enabled" : "disabled");
+#else
+ if (value)
+ xf86Msg(X_WARNING, "VTSysReq is not supported on this OS\n");
+#endif
+ }
+
+ xf86Info.pmFlag = TRUE;
+ if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value))
+ xf86Info.pmFlag = !value;
+ {
+ if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) {
+ if (!xf86NameCmp(s,"flush")) {
+ xf86Msg(X_CONFIG, "Flushing logfile enabled\n");
+ xf86Info.log = LogFlush;
+ LogSetParameter(XLOG_FLUSH, TRUE);
+ } else if (!xf86NameCmp(s,"sync")) {
+ xf86Msg(X_CONFIG, "Syncing logfile enabled\n");
+ xf86Info.log = LogSync;
+ LogSetParameter(XLOG_FLUSH, TRUE);
+ LogSetParameter(XLOG_SYNC, TRUE);
+ } else {
+ xf86Msg(X_WARNING,"Unknown Log option\n");
+ }
+ }
+ }
+
+ {
+ if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))){
+ int policy = PictureParseCmapPolicy (s);
+ if (policy == PictureCmapPolicyInvalid)
+ xf86Msg(X_WARNING, "Unknown colormap policy \"%s\"\n", s);
+ else
+ {
+ xf86Msg(X_CONFIG, "Render colormap policy set to %s\n", s);
+ PictureCmapPolicy = policy;
+ }
+ }
+ }
+
+#ifdef RANDR
+ xf86Info.disableRandR = FALSE;
+ xf86Info.randRFrom = X_DEFAULT;
+ if (xf86GetOptValBool(FlagOptions, FLAG_RANDR, &value)) {
+ xf86Info.disableRandR = !value;
+ xf86Info.randRFrom = X_CONFIG;
+ }
+#endif
+
+ xf86Info.aiglx = TRUE;
+ xf86Info.aiglxFrom = X_DEFAULT;
+ if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
+ xf86Info.aiglx = value;
+ xf86Info.aiglxFrom = X_CONFIG;
+ }
+
+#ifdef GLXEXT
+ xf86Info.glxVisuals = XF86_GlxVisualsTypical;
+ xf86Info.glxVisualsFrom = X_DEFAULT;
+ if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) {
+ if (!xf86NameCmp(s, "minimal")) {
+ xf86Info.glxVisuals = XF86_GlxVisualsMinimal;
+ } else if (!xf86NameCmp(s, "typical")) {
+ xf86Info.glxVisuals = XF86_GlxVisualsTypical;
+ } else if (!xf86NameCmp(s, "all")) {
+ xf86Info.glxVisuals = XF86_GlxVisualsAll;
+ } else {
+ xf86Msg(X_WARNING,"Unknown GlxVisuals option\n");
+ }
+ }
+
+ if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
+ xf86Info.aiglx = value;
+ xf86Info.aiglxFrom = X_CONFIG;
+ }
+#endif
+
+ /* if we're not hotplugging, force some input devices to exist */
+ xf86Info.forceInputDevices = !(xf86Info.autoAddDevices && xf86Info.autoEnableDevices);
+
+ /* when forcing input devices, we use kbd. otherwise evdev, so use the
+ * evdev rules set. */
+#if defined(linux)
+ if (!xf86Info.forceInputDevices)
+ set.rules = "evdev";
+#endif
+ XkbSetRulesDflts(&set);
+
+ xf86Info.useDefaultFontPath = TRUE;
+ xf86Info.useDefaultFontPathFrom = X_DEFAULT;
+ if (xf86GetOptValBool(FlagOptions, FLAG_USE_DEFAULT_FONT_PATH, &value)) {
+ xf86Info.useDefaultFontPath = value;
+ xf86Info.useDefaultFontPathFrom = X_CONFIG;
+ }
+
+/* Make sure that timers don't overflow CARD32's after multiplying */
+#define MAX_TIME_IN_MIN (0x7fffffff / MILLI_PER_MIN)
+
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_SAVER_BLANKTIME, &i);
+ if ((i >= 0) && (i < MAX_TIME_IN_MIN))
+ ScreenSaverTime = defaultScreenSaverTime = i * MILLI_PER_MIN;
+ else if (i != -1)
+ xf86ConfigError("BlankTime value %d outside legal range of 0 - %d minutes",
+ i, MAX_TIME_IN_MIN);
+
+#ifdef DPMSExtension
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_DPMS_STANDBYTIME, &i);
+ if ((i >= 0) && (i < MAX_TIME_IN_MIN))
+ DPMSStandbyTime = i * MILLI_PER_MIN;
+ else if (i != -1)
+ xf86ConfigError("StandbyTime value %d outside legal range of 0 - %d minutes",
+ i, MAX_TIME_IN_MIN);
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_DPMS_SUSPENDTIME, &i);
+ if ((i >= 0) && (i < MAX_TIME_IN_MIN))
+ DPMSSuspendTime = i * MILLI_PER_MIN;
+ else if (i != -1)
+ xf86ConfigError("SuspendTime value %d outside legal range of 0 - %d minutes",
+ i, MAX_TIME_IN_MIN);
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_DPMS_OFFTIME, &i);
+ if ((i >= 0) && (i < MAX_TIME_IN_MIN))
+ DPMSOffTime = i * MILLI_PER_MIN;
+ else if (i != -1)
+ xf86ConfigError("OffTime value %d outside legal range of 0 - %d minutes",
+ i, MAX_TIME_IN_MIN);
+#endif
+
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_PIXMAP, &i);
+ switch (i) {
+ case 24:
+ pix24 = Pix24Use24;
+ break;
+ case 32:
+ pix24 = Pix24Use32;
+ break;
+ case -1:
+ break;
+ default:
+ xf86ConfigError("Pixmap option's value (%d) must be 24 or 32\n", i);
+ return FALSE;
+ }
+ if (xf86Pix24 != Pix24DontCare) {
+ xf86Info.pixmap24 = xf86Pix24;
+ xf86Info.pix24From = X_CMDLINE;
+ } else if (pix24 != Pix24DontCare) {
+ xf86Info.pixmap24 = pix24;
+ xf86Info.pix24From = X_CONFIG;
+ } else {
+ xf86Info.pixmap24 = Pix24DontCare;
+ xf86Info.pix24From = X_DEFAULT;
+ }
+#ifdef SUPPORT_PC98
+ if (xf86GetOptValBool(FlagOptions, FLAG_PC98, &value)) {
+ xf86Info.pc98 = value;
+ if (value) {
+ xf86Msg(X_CONFIG, "Japanese PC98 architecture\n");
+ }
+ } else
+ if (detectPC98()) {
+ xf86Info.pc98 = TRUE;
+ xf86Msg(X_PROBED, "Japanese PC98 architecture\n");
+ }
+#endif
+
+#ifdef PANORAMIX
+ from = X_DEFAULT;
+ if (!noPanoramiXExtension)
+ from = X_CMDLINE;
+ else if (xf86GetOptValBool(FlagOptions, FLAG_XINERAMA, &value)) {
+ noPanoramiXExtension = !value;
+ from = X_CONFIG;
+ }
+ if (!noPanoramiXExtension)
+ xf86Msg(from, "Xinerama: enabled\n");
+#endif
+
+#ifdef DRI2
+ xf86Info.dri2 = FALSE;
+ xf86Info.dri2From = X_DEFAULT;
+ if (xf86GetOptValBool(FlagOptions, FLAG_DRI2, &value)) {
+ xf86Info.dri2 = value;
+ xf86Info.dri2From = X_CONFIG;
+ }
+#endif
+
+ return TRUE;
+}
+
+Bool xf86DRI2Enabled(void)
+{
+ return xf86Info.dri2;
+}
+
+/*
+ * Locate the core input devices. These can be specified/located in
+ * the following ways, in order of priority:
+ *
+ * 1. The InputDevices named by the -pointer and -keyboard command line
+ * options.
+ * 2. The "CorePointer" and "CoreKeyboard" InputDevices referred to by
+ * the active ServerLayout.
+ * 3. The first InputDevices marked as "CorePointer" and "CoreKeyboard".
+ * 4. The first InputDevices that use 'keyboard' or 'kbd' and a valid mouse
+ * driver (mouse, synaptics, evdev, vmmouse, void)
+ * 5. Default devices with an empty (default) configuration. These defaults
+ * will reference the 'mouse' and 'keyboard' drivers.
+ */
+
+static Bool
+checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
+{
+ InputInfoPtr corePointer = NULL, coreKeyboard = NULL;
+ Bool foundPointer = FALSE, foundKeyboard = FALSE;
+ const char *pointerMsg = NULL, *keyboardMsg = NULL;
+ InputInfoPtr *devs, /* iterator */
+ indp;
+ InputInfoRec 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 };
+
+ /*
+ * First check if a core pointer or core keyboard have been specified
+ * in the active ServerLayout. If more than one is specified for either,
+ * remove the core attribute from the later ones.
+ */
+ for (devs = servlayoutp->inputs; devs && *devs; devs++) {
+ indp = *devs;
+ if (indp->options &&
+ 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;
+
+ /* 1. Check for the -pointer command line option. */
+ if (xf86PointerName) {
+ confInput = xf86findInput(xf86PointerName,
+ xf86configptr->conf_input_lst);
+ if (!confInput) {
+ xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
+ xf86PointerName);
+ return FALSE;
+ }
+ from = X_CMDLINE;
+ /*
+ * If one was already specified in the ServerLayout, it needs to be
+ * 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--;
+ }
+ corePointer = NULL;
+ foundPointer = TRUE;
+ }
+
+ /* 2. ServerLayout-specified core pointer. */
+ if (corePointer) {
+ foundPointer = TRUE;
+ from = X_CONFIG;
+ }
+
+ /* 3. First core pointer device. */
+ if (!foundPointer && (xf86Info.forceInputDevices || implicitLayout)) {
+ XF86ConfInputPtr p;
+
+ for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
+ if (p->inp_option_lst &&
+ xf86CheckBoolOption(p->inp_option_lst, "CorePointer", FALSE)) {
+ confInput = p;
+ foundPointer = TRUE;
+ from = X_DEFAULT;
+ pointerMsg = "first core pointer device";
+ break;
+ }
+ }
+ }
+
+ /* 4. First pointer with an allowed mouse driver. */
+ if (!foundPointer && xf86Info.forceInputDevices) {
+ const char **driver = mousedrivers;
+ confInput = xf86findInput(CONF_IMPLICIT_POINTER,
+ xf86configptr->conf_input_lst);
+ while (*driver && !confInput) {
+ confInput = xf86findInputByDriver(*driver,
+ xf86configptr->conf_input_lst);
+ driver++;
+ }
+ if (confInput) {
+ foundPointer = TRUE;
+ from = X_DEFAULT;
+ pointerMsg = "first mouse device";
+ }
+ }
+
+ /* 5. Built-in default. */
+ if (!foundPointer && xf86Info.forceInputDevices) {
+ memset(&defPtr, 0, sizeof(defPtr));
+ defPtr.inp_identifier = strdup("<default pointer>");
+ defPtr.inp_driver = strdup("mouse");
+ confInput = &defPtr;
+ foundPointer = TRUE;
+ from = X_DEFAULT;
+ pointerMsg = "default mouse configuration";
+ }
+
+ /* 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));
+ *devs[count - 1] = Pointer;
+ devs[count - 1]->options =
+ xf86addNewOption(devs[count -1]->options,
+ xnfstrdup("CorePointer"), NULL);
+ devs[count] = NULL;
+ servlayoutp->inputs = devs;
+ }
+ }
+
+ if (!foundPointer && xf86Info.forceInputDevices) {
+ /* This shouldn't happen. */
+ xf86Msg(X_ERROR, "Cannot locate a core pointer device.\n");
+ 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));
+ *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. */
+ if (xf86KeyboardName) {
+ confInput = xf86findInput(xf86KeyboardName,
+ xf86configptr->conf_input_lst);
+ if (!confInput) {
+ xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
+ xf86KeyboardName);
+ return FALSE;
+ }
+ from = X_CMDLINE;
+ /*
+ * If one was already specified in the ServerLayout, it needs to be
+ * 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--;
+ }
+ coreKeyboard = NULL;
+ foundKeyboard = TRUE;
+ }
+
+ /* 2. ServerLayout-specified core keyboard. */
+ if (coreKeyboard) {
+ foundKeyboard = TRUE;
+ from = X_CONFIG;
+ }
+
+ /* 3. First core keyboard device. */
+ if (!foundKeyboard && (xf86Info.forceInputDevices || implicitLayout)) {
+ XF86ConfInputPtr p;
+
+ for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
+ if (p->inp_option_lst &&
+ xf86CheckBoolOption(p->inp_option_lst, "CoreKeyboard", FALSE)) {
+ confInput = p;
+ foundKeyboard = TRUE;
+ from = X_DEFAULT;
+ keyboardMsg = "first core keyboard device";
+ break;
+ }
+ }
+ }
+
+ /* 4. First keyboard with 'keyboard' or 'kbd' as the driver. */
+ if (!foundKeyboard && xf86Info.forceInputDevices) {
+ confInput = xf86findInput(CONF_IMPLICIT_KEYBOARD,
+ xf86configptr->conf_input_lst);
+ if (!confInput) {
+ confInput = xf86findInputByDriver("kbd",
+ xf86configptr->conf_input_lst);
+ }
+ if (confInput) {
+ foundKeyboard = TRUE;
+ from = X_DEFAULT;
+ keyboardMsg = "first keyboard device";
+ }
+ }
+
+ /* 5. Built-in default. */
+ if (!foundKeyboard && xf86Info.forceInputDevices) {
+ memset(&defKbd, 0, sizeof(defKbd));
+ defKbd.inp_identifier = strdup("<default keyboard>");
+ defKbd.inp_driver = strdup("kbd");
+ confInput = &defKbd;
+ foundKeyboard = TRUE;
+ keyboardMsg = "default keyboard configuration";
+ from = X_DEFAULT;
+ }
+
+ /* 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));
+ *devs[count - 1] = Keyboard;
+ devs[count - 1]->options =
+ xf86addNewOption(devs[count - 1]->options,
+ xnfstrdup("CoreKeyboard"), NULL);
+ devs[count] = NULL;
+ servlayoutp->inputs = devs;
+ }
+ }
+
+ if (!foundKeyboard && xf86Info.forceInputDevices) {
+ /* This shouldn't happen. */
+ xf86Msg(X_ERROR, "Cannot locate a core keyboard device.\n");
+ return FALSE;
+ }
+
+ if (pointerMsg) {
+ if (implicitLayout)
+ xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
+ pointerMsg);
+ else
+ xf86Msg(X_DEFAULT, "The core pointer device wasn't specified "
+ "explicitly in the layout.\n"
+ "\tUsing the %s.\n", pointerMsg);
+ }
+
+ if (keyboardMsg) {
+ if (implicitLayout)
+ xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
+ keyboardMsg);
+ else
+ xf86Msg(X_DEFAULT, "The core keyboard device wasn't specified "
+ "explicitly in the layout.\n"
+ "\tUsing the %s.\n", keyboardMsg);
+ }
+
+ if (!xf86Info.forceInputDevices && !(foundPointer && foundKeyboard)) {
+#if defined(CONFIG_HAL) || defined(CONFIG_UDEV)
+ const char *config_backend;
+#if defined(CONFIG_HAL)
+ config_backend = "HAL";
+#else
+ config_backend = "udev";
+#endif
+ xf86Msg(X_INFO, "The server relies on %s to provide the list of "
+ "input devices.\n\tIf no devices become available, "
+ "reconfigure %s or disable AutoAddDevices.\n",
+ config_backend, config_backend);
+#else
+ xf86Msg(X_WARNING, "Hotplugging requested but the server was "
+ "compiled without a config backend. "
+ "No input devices were configured, the server "
+ "will start without any input devices.\n");
+#endif
+ }
+
+ return TRUE;
+}
+
+typedef enum {
+ LAYOUT_ISOLATEDEVICE,
+ LAYOUT_SINGLECARD
+} LayoutValues;
+
+static OptionInfoRec LayoutOptions[] = {
+ { LAYOUT_ISOLATEDEVICE, "IsolateDevice", OPTV_STRING,
+ {0}, FALSE },
+ { LAYOUT_SINGLECARD, "SingleCard", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { -1, NULL, OPTV_NONE,
+ {0}, FALSE },
+};
+
+static Bool
+configInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp)
+{
+ XF86ConfInputrefPtr irp;
+ InputInfoPtr *indp;
+ int count = 0;
+
+ /*
+ * Count the number of input devices.
+ */
+ irp = layout->lay_input_lst;
+ while (irp) {
+ count++;
+ irp = (XF86ConfInputrefPtr)irp->list.next;
+ }
+ DebugF("Found %d input devices in the layout section %s\n",
+ count, layout->lay_identifier);
+ indp = xnfcalloc((count + 1), sizeof(InputInfoPtr));
+ indp[count] = NULL;
+ irp = layout->lay_input_lst;
+ count = 0;
+ while (irp) {
+ indp[count] = xf86AllocateInput();
+ if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) {
+ do {
+ free(indp[count]);
+ } while(count--);
+ free(indp);
+ return FALSE;
+ }
+ indp[count]->options = xf86OptionListMerge(indp[count]->options,
+ irp->iref_option_lst);
+ count++;
+ irp = (XF86ConfInputrefPtr)irp->list.next;
+ }
+ servlayoutp->inputs = indp;
+
+ return TRUE;
+}
+
+
+/*
+ * figure out which layout is active, which screens are used in that layout,
+ * which drivers and monitors are used in these screens
+ */
+static Bool
+configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
+ char *default_layout)
+{
+ XF86ConfAdjacencyPtr adjp;
+ XF86ConfInactivePtr idp;
+ int saved_count, count = 0;
+ int scrnum;
+ XF86ConfLayoutPtr l;
+ MessageType from;
+ screenLayoutPtr slp;
+ GDevPtr gdp;
+ int i = 0, j;
+
+ if (!servlayoutp)
+ return FALSE;
+
+ /*
+ * which layout section is the active one?
+ *
+ * If there is a -layout command line option, use that one, otherwise
+ * pick the first one.
+ */
+ from = X_DEFAULT;
+ if (xf86LayoutName != NULL)
+ from = X_CMDLINE;
+ else if (default_layout) {
+ xf86LayoutName = default_layout;
+ from = X_CONFIG;
+ }
+ if (xf86LayoutName != NULL) {
+ if ((l = xf86findLayout(xf86LayoutName, conf_layout)) == NULL) {
+ xf86Msg(X_ERROR, "No ServerLayout section called \"%s\"\n",
+ xf86LayoutName);
+ return FALSE;
+ }
+ conf_layout = l;
+ }
+ xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier);
+ adjp = conf_layout->lay_adjacency_lst;
+
+ /*
+ * we know that each screen is referenced exactly once on the left side
+ * of a layout statement in the Layout section. So to allocate the right
+ * size for the array we do a quick walk of the list to figure out how
+ * many sections we have
+ */
+ while (adjp) {
+ count++;
+ adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
+ }
+
+ DebugF("Found %d screens in the layout section %s",
+ count, conf_layout->lay_identifier);
+ if (!count) /* alloc enough storage even if no screen is specified */
+ count = 1;
+
+ slp = xnfcalloc(1, (count + 1) * sizeof(screenLayoutRec));
+ slp[count].screen = NULL;
+ /*
+ * now that we have storage, loop over the list again and fill in our
+ * data structure; at this point we do not fill in the adjacency
+ * information as it is not clear if we need it at all
+ */
+ adjp = conf_layout->lay_adjacency_lst;
+ count = 0;
+ while (adjp) {
+ slp[count].screen = xnfcalloc(1, sizeof(confScreenRec));
+ if (adjp->adj_scrnum < 0)
+ scrnum = count;
+ else
+ scrnum = adjp->adj_scrnum;
+ if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum,
+ X_CONFIG)) {
+ do {
+ free(slp[count].screen);
+ } while(count--);
+ free(slp);
+ return FALSE;
+ }
+ slp[count].x = adjp->adj_x;
+ slp[count].y = adjp->adj_y;
+ slp[count].refname = adjp->adj_refscreen;
+ switch (adjp->adj_where) {
+ case CONF_ADJ_OBSOLETE:
+ slp[count].where = PosObsolete;
+ slp[count].topname = adjp->adj_top_str;
+ slp[count].bottomname = adjp->adj_bottom_str;
+ slp[count].leftname = adjp->adj_left_str;
+ slp[count].rightname = adjp->adj_right_str;
+ break;
+ case CONF_ADJ_ABSOLUTE:
+ slp[count].where = PosAbsolute;
+ break;
+ case CONF_ADJ_RIGHTOF:
+ slp[count].where = PosRightOf;
+ break;
+ case CONF_ADJ_LEFTOF:
+ slp[count].where = PosLeftOf;
+ break;
+ case CONF_ADJ_ABOVE:
+ slp[count].where = PosAbove;
+ break;
+ case CONF_ADJ_BELOW:
+ slp[count].where = PosBelow;
+ break;
+ case CONF_ADJ_RELATIVE:
+ slp[count].where = PosRelative;
+ break;
+ }
+ count++;
+ adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
+ }
+
+ /* No screen was specified in the layout. take the first one from the
+ * config file, or - if it is NULL - configScreen autogenerates one for
+ * us */
+ if (!count)
+ {
+ slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
+ if (!configScreen(slp[0].screen, xf86configptr->conf_screen_lst,
+ 0, X_CONFIG)) {
+ free(slp[0].screen);
+ free(slp);
+ return FALSE;
+ }
+ }
+
+ /* XXX Need to tie down the upper left screen. */
+
+ /* Fill in the refscreen and top/bottom/left/right values */
+ for (i = 0; i < count; i++) {
+ for (j = 0; j < count; j++) {
+ if (slp[i].refname &&
+ strcmp(slp[i].refname, slp[j].screen->id) == 0) {
+ slp[i].refscreen = slp[j].screen;
+ }
+ if (slp[i].topname &&
+ strcmp(slp[i].topname, slp[j].screen->id) == 0) {
+ slp[i].top = slp[j].screen;
+ }
+ if (slp[i].bottomname &&
+ strcmp(slp[i].bottomname, slp[j].screen->id) == 0) {
+ slp[i].bottom = slp[j].screen;
+ }
+ if (slp[i].leftname &&
+ strcmp(slp[i].leftname, slp[j].screen->id) == 0) {
+ slp[i].left = slp[j].screen;
+ }
+ if (slp[i].rightname &&
+ strcmp(slp[i].rightname, slp[j].screen->id) == 0) {
+ slp[i].right = slp[j].screen;
+ }
+ }
+ if (slp[i].where != PosObsolete
+ && slp[i].where != PosAbsolute
+ && !slp[i].refscreen) {
+ xf86Msg(X_ERROR,"Screen %s doesn't exist: deleting placement\n",
+ slp[i].refname);
+ slp[i].where = PosAbsolute;
+ slp[i].x = 0;
+ slp[i].y = 0;
+ }
+ }
+
+ if (!count)
+ saved_count = 1;
+ else
+ saved_count = count;
+ /*
+ * Count the number of inactive devices.
+ */
+ count = 0;
+ idp = conf_layout->lay_inactive_lst;
+ while (idp) {
+ count++;
+ idp = (XF86ConfInactivePtr)idp->list.next;
+ }
+ DebugF("Found %d inactive devices in the layout section %s\n",
+ count, conf_layout->lay_identifier);
+ gdp = xnfalloc((count + 1) * sizeof(GDevRec));
+ gdp[count].identifier = NULL;
+ idp = conf_layout->lay_inactive_lst;
+ count = 0;
+ while (idp) {
+ if (!configDevice(&gdp[count], idp->inactive_device, FALSE))
+ goto bail;
+ count++;
+ idp = (XF86ConfInactivePtr)idp->list.next;
+ }
+
+ if (!configInputDevices(conf_layout, servlayoutp))
+ goto bail;
+
+ servlayoutp->id = conf_layout->lay_identifier;
+ servlayoutp->screens = slp;
+ servlayoutp->inactives = gdp;
+ servlayoutp->options = conf_layout->lay_option_lst;
+ from = X_DEFAULT;
+
+ return TRUE;
+
+bail:
+ do {
+ free(slp[saved_count].screen);
+ } while(saved_count--);
+ free(slp);
+ free(gdp);
+ return FALSE;
+}
+
+/*
+ * No layout section, so find the first Screen section and set that up as
+ * the only active screen.
+ */
+static Bool
+configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
+ XF86ConfigPtr xf86configptr)
+{
+ MessageType from;
+ XF86ConfScreenPtr s;
+ screenLayoutPtr slp;
+ InputInfoPtr *indp;
+ XF86ConfLayoutRec layout;
+
+ if (!servlayoutp)
+ return FALSE;
+
+ /*
+ * which screen section is the active one?
+ *
+ * If there is a -screen option, use that one, otherwise use the first
+ * one.
+ */
+
+ from = X_CONFIG;
+ if (xf86ScreenName != NULL) {
+ if ((s = xf86findScreen(xf86ScreenName, conf_screen)) == NULL) {
+ xf86Msg(X_ERROR, "No Screen section called \"%s\"\n",
+ xf86ScreenName);
+ return FALSE;
+ }
+ conf_screen = s;
+ from = X_CMDLINE;
+ }
+
+ /* We have exactly one screen */
+
+ slp = xnfcalloc(1, 2 * sizeof(screenLayoutRec));
+ slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
+ slp[1].screen = NULL;
+ if (!configScreen(slp[0].screen, conf_screen, 0, from)) {
+ free(slp);
+ return FALSE;
+ }
+ servlayoutp->id = "(implicit)";
+ servlayoutp->screens = slp;
+ servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec));
+ servlayoutp->options = NULL;
+
+ memset(&layout, 0, sizeof(layout));
+ layout.lay_identifier = servlayoutp->id;
+ if (xf86layoutAddInputDevices(xf86configptr, &layout) > 0) {
+ if (!configInputDevices(&layout, servlayoutp))
+ return FALSE;
+ from = X_DEFAULT;
+ } else {
+ /* Set up an empty input device list, then look for some core devices. */
+ indp = xnfalloc(sizeof(InputInfoPtr));
+ *indp = NULL;
+ servlayoutp->inputs = indp;
+ }
+
+ return TRUE;
+}
+
+static Bool
+configXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor)
+{
+ int count = 0;
+ XF86ConfVideoPortPtr conf_port;
+
+ xf86Msg(X_CONFIG, "| |-->VideoAdaptor \"%s\"\n",
+ conf_adaptor->va_identifier);
+ adaptor->identifier = conf_adaptor->va_identifier;
+ adaptor->options = conf_adaptor->va_option_lst;
+ if (conf_adaptor->va_busid || conf_adaptor->va_driver) {
+ xf86Msg(X_CONFIG, "| | Unsupported device type, skipping entry\n");
+ return FALSE;
+ }
+
+ /*
+ * figure out how many videoport subsections there are and fill them in
+ */
+ conf_port = conf_adaptor->va_port_lst;
+ while(conf_port) {
+ count++;
+ conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
+ }
+ adaptor->ports = xnfalloc((count) * sizeof(confXvPortRec));
+ adaptor->numports = count;
+ count = 0;
+ conf_port = conf_adaptor->va_port_lst;
+ while(conf_port) {
+ adaptor->ports[count].identifier = conf_port->vp_identifier;
+ adaptor->ports[count].options = conf_port->vp_option_lst;
+ count++;
+ conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
+ }
+
+ return TRUE;
+}
+
+static Bool
+configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
+ MessageType from)
+{
+ int count = 0;
+ XF86ConfDisplayPtr dispptr;
+ XF86ConfAdaptorLinkPtr conf_adaptor;
+ Bool defaultMonitor = FALSE;
+ XF86ConfScreenRec local_conf_screen;
+
+ if (!conf_screen) {
+ memset(&local_conf_screen, 0, sizeof(local_conf_screen));
+ conf_screen = &local_conf_screen;
+ conf_screen->scrn_identifier = "Default Screen Section";
+ xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n");
+ }
+
+ xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
+ scrnum);
+ /*
+ * now we fill in the elements of the screen
+ */
+ screenp->id = conf_screen->scrn_identifier;
+ screenp->screennum = scrnum;
+ screenp->defaultdepth = conf_screen->scrn_defaultdepth;
+ screenp->defaultbpp = conf_screen->scrn_defaultbpp;
+ screenp->defaultfbbpp = conf_screen->scrn_defaultfbbpp;
+ screenp->monitor = xnfcalloc(1, sizeof(MonRec));
+ /* If no monitor is specified, create a default one. */
+ if (!conf_screen->scrn_monitor) {
+ XF86ConfMonitorRec defMon;
+
+ memset(&defMon, 0, sizeof(defMon));
+ defMon.mon_identifier = "<default monitor>";
+ if (!configMonitor(screenp->monitor, &defMon))
+ return FALSE;
+ defaultMonitor = TRUE;
+ } else {
+ if (!configMonitor(screenp->monitor,conf_screen->scrn_monitor))
+ return FALSE;
+ }
+ /* Configure the device. If there isn't one configured, attach to the
+ * first inactive one that we can configure. If there's none that work,
+ * set it to NULL so that the section can be autoconfigured later */
+ screenp->device = xnfcalloc(1, sizeof(GDevRec));
+ if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) {
+ conf_screen->scrn_device = xf86configptr->conf_device_lst;
+ xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
+ "\tUsing the first device section listed.\n", screenp->id);
+ }
+ if (configDevice(screenp->device,conf_screen->scrn_device, TRUE)) {
+ screenp->device->myScreenSection = screenp;
+ } else {
+ screenp->device = NULL;
+ }
+ screenp->options = conf_screen->scrn_option_lst;
+
+ /*
+ * figure out how many display subsections there are and fill them in
+ */
+ dispptr = conf_screen->scrn_display_lst;
+ while(dispptr) {
+ count++;
+ dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
+ }
+ screenp->displays = xnfalloc((count) * sizeof(DispRec));
+ screenp->numdisplays = count;
+
+ /* Fill in the default Virtual size, if any */
+ if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) {
+ for (count = 0, dispptr = conf_screen->scrn_display_lst;
+ dispptr;
+ dispptr = (XF86ConfDisplayPtr)dispptr->list.next, count++) {
+ screenp->displays[count].virtualX = conf_screen->scrn_virtualX;
+ screenp->displays[count].virtualY = conf_screen->scrn_virtualY;
+ }
+ }
+
+ /* Now do the per-Display Virtual sizes */
+ count = 0;
+ dispptr = conf_screen->scrn_display_lst;
+ while(dispptr) {
+ configDisplay(&(screenp->displays[count]),dispptr);
+ count++;
+ dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
+ }
+
+ /*
+ * figure out how many videoadaptor references there are and fill them in
+ */
+ conf_adaptor = conf_screen->scrn_adaptor_lst;
+ while(conf_adaptor) {
+ count++;
+ conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
+ }
+ screenp->xvadaptors = xnfalloc((count) * sizeof(confXvAdaptorRec));
+ screenp->numxvadaptors = 0;
+ conf_adaptor = conf_screen->scrn_adaptor_lst;
+ while(conf_adaptor) {
+ if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]),
+ conf_adaptor->al_adaptor))
+ screenp->numxvadaptors++;
+ conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
+ }
+
+ if (defaultMonitor) {
+ xf86Msg(X_DEFAULT, "No monitor specified for screen \"%s\".\n"
+ "\tUsing a default monitor configuration.\n", screenp->id);
+ }
+ return TRUE;
+}
+
+typedef enum {
+ MON_REDUCEDBLANKING,
+ MON_MAX_PIX_CLOCK,
+} MonitorValues;
+
+static OptionInfoRec MonitorOptions[] = {
+ { MON_REDUCEDBLANKING, "ReducedBlanking", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { MON_MAX_PIX_CLOCK, "MaxPixClock", OPTV_FREQ,
+ {0}, FALSE },
+ { -1, NULL, OPTV_NONE,
+ {0}, FALSE },
+};
+
+static Bool
+configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor)
+{
+ int count;
+ DisplayModePtr mode,last = NULL;
+ XF86ConfModeLinePtr cmodep;
+ XF86ConfModesPtr modes;
+ XF86ConfModesLinkPtr modeslnk = conf_monitor->mon_modes_sect_lst;
+ Gamma zeros = {0.0, 0.0, 0.0};
+ float badgamma = 0.0;
+ double maxPixClock;
+
+ xf86Msg(X_CONFIG, "| |-->Monitor \"%s\"\n",
+ conf_monitor->mon_identifier);
+ monitorp->id = conf_monitor->mon_identifier;
+ monitorp->vendor = conf_monitor->mon_vendor;
+ monitorp->model = conf_monitor->mon_modelname;
+ monitorp->Modes = NULL;
+ monitorp->Last = NULL;
+ monitorp->gamma = zeros;
+ monitorp->widthmm = conf_monitor->mon_width;
+ monitorp->heightmm = conf_monitor->mon_height;
+ monitorp->reducedblanking = FALSE;
+ monitorp->maxPixClock = 0;
+ monitorp->options = conf_monitor->mon_option_lst;
+
+ /*
+ * fill in the monitor structure
+ */
+ for( count = 0 ;
+ count < conf_monitor->mon_n_hsync && count < MAX_HSYNC;
+ count++) {
+ monitorp->hsync[count].hi = conf_monitor->mon_hsync[count].hi;
+ monitorp->hsync[count].lo = conf_monitor->mon_hsync[count].lo;
+ }
+ monitorp->nHsync = count;
+ for( count = 0 ;
+ count < conf_monitor->mon_n_vrefresh && count < MAX_VREFRESH;
+ count++) {
+ monitorp->vrefresh[count].hi = conf_monitor->mon_vrefresh[count].hi;
+ monitorp->vrefresh[count].lo = conf_monitor->mon_vrefresh[count].lo;
+ }
+ monitorp->nVrefresh = count;
+
+ /*
+ * first we collect the mode lines from the UseModes directive
+ */
+ while(modeslnk)
+ {
+ modes = xf86findModes (modeslnk->ml_modes_str,
+ xf86configptr->conf_modes_lst);
+ modeslnk->ml_modes = modes;
+
+
+ /* now add the modes found in the modes
+ section to the list of modes for this
+ monitor unless it has been added before
+ because we are reusing the same section
+ for another screen */
+ if (xf86itemNotSublist(
+ (GenericListPtr)conf_monitor->mon_modeline_lst,
+ (GenericListPtr)modes->mon_modeline_lst)) {
+ conf_monitor->mon_modeline_lst = (XF86ConfModeLinePtr)
+ xf86addListItem(
+ (GenericListPtr)conf_monitor->mon_modeline_lst,
+ (GenericListPtr)modes->mon_modeline_lst);
+ }
+ modeslnk = modeslnk->list.next;
+ }
+
+ /*
+ * we need to hook in the mode lines now
+ * here both data structures use lists, only our internal one
+ * is double linked
+ */
+ cmodep = conf_monitor->mon_modeline_lst;
+ while( cmodep ) {
+ mode = xnfcalloc(1, sizeof(DisplayModeRec));
+ mode->type = 0;
+ mode->Clock = cmodep->ml_clock;
+ mode->HDisplay = cmodep->ml_hdisplay;
+ mode->HSyncStart = cmodep->ml_hsyncstart;
+ mode->HSyncEnd = cmodep->ml_hsyncend;
+ mode->HTotal = cmodep->ml_htotal;
+ mode->VDisplay = cmodep->ml_vdisplay;
+ mode->VSyncStart = cmodep->ml_vsyncstart;
+ mode->VSyncEnd = cmodep->ml_vsyncend;
+ mode->VTotal = cmodep->ml_vtotal;
+ mode->Flags = cmodep->ml_flags;
+ mode->HSkew = cmodep->ml_hskew;
+ mode->VScan = cmodep->ml_vscan;
+ mode->name = xnfstrdup(cmodep->ml_identifier);
+ if( last ) {
+ mode->prev = last;
+ last->next = mode;
+ }
+ else {
+ /*
+ * this is the first mode
+ */
+ monitorp->Modes = mode;
+ mode->prev = NULL;
+ }
+ last = mode;
+ cmodep = (XF86ConfModeLinePtr)cmodep->list.next;
+ }
+ if(last){
+ last->next = NULL;
+ }
+ monitorp->Last = last;
+
+ /* add the (VESA) default modes */
+ if (! addDefaultModes(monitorp) )
+ return FALSE;
+
+ if (conf_monitor->mon_gamma_red > GAMMA_ZERO)
+ monitorp->gamma.red = conf_monitor->mon_gamma_red;
+ if (conf_monitor->mon_gamma_green > GAMMA_ZERO)
+ monitorp->gamma.green = conf_monitor->mon_gamma_green;
+ if (conf_monitor->mon_gamma_blue > GAMMA_ZERO)
+ monitorp->gamma.blue = conf_monitor->mon_gamma_blue;
+
+ /* Check that the gamma values are within range */
+ if (monitorp->gamma.red > GAMMA_ZERO &&
+ (monitorp->gamma.red < GAMMA_MIN ||
+ monitorp->gamma.red > GAMMA_MAX)) {
+ badgamma = monitorp->gamma.red;
+ } else if (monitorp->gamma.green > GAMMA_ZERO &&
+ (monitorp->gamma.green < GAMMA_MIN ||
+ monitorp->gamma.green > GAMMA_MAX)) {
+ badgamma = monitorp->gamma.green;
+ } else if (monitorp->gamma.blue > GAMMA_ZERO &&
+ (monitorp->gamma.blue < GAMMA_MIN ||
+ monitorp->gamma.blue > GAMMA_MAX)) {
+ badgamma = monitorp->gamma.blue;
+ }
+ if (badgamma > GAMMA_ZERO) {
+ xf86ConfigError("Gamma value %.f is out of range (%.2f - %.1f)\n",
+ badgamma, GAMMA_MIN, GAMMA_MAX);
+ return FALSE;
+ }
+
+ xf86ProcessOptions(-1, monitorp->options, MonitorOptions);
+ xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING,
+ &monitorp->reducedblanking);
+ if (xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ,
+ &maxPixClock) == TRUE) {
+ monitorp->maxPixClock = (int) maxPixClock;
+ }
+
+ return TRUE;
+}
+
+static int
+lookupVisual(const char *visname)
+{
+ int i;
+
+ if (!visname || !*visname)
+ return -1;
+
+ for (i = 0; i <= DirectColor; i++) {
+ if (!xf86nameCompare(visname, xf86VisualNames[i]))
+ break;
+ }
+
+ if (i <= DirectColor)
+ return i;
+
+ return -1;
+}
+
+
+static Bool
+configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
+{
+ int count = 0;
+ XF86ModePtr modep;
+
+ displayp->frameX0 = conf_display->disp_frameX0;
+ displayp->frameY0 = conf_display->disp_frameY0;
+ displayp->virtualX = conf_display->disp_virtualX;
+ displayp->virtualY = conf_display->disp_virtualY;
+ displayp->depth = conf_display->disp_depth;
+ displayp->fbbpp = conf_display->disp_bpp;
+ displayp->weight.red = conf_display->disp_weight.red;
+ displayp->weight.green = conf_display->disp_weight.green;
+ displayp->weight.blue = conf_display->disp_weight.blue;
+ displayp->blackColour.red = conf_display->disp_black.red;
+ displayp->blackColour.green = conf_display->disp_black.green;
+ displayp->blackColour.blue = conf_display->disp_black.blue;
+ displayp->whiteColour.red = conf_display->disp_white.red;
+ displayp->whiteColour.green = conf_display->disp_white.green;
+ displayp->whiteColour.blue = conf_display->disp_white.blue;
+ displayp->options = conf_display->disp_option_lst;
+ if (conf_display->disp_visual) {
+ displayp->defaultVisual = lookupVisual(conf_display->disp_visual);
+ if (displayp->defaultVisual == -1) {
+ xf86ConfigError("Invalid visual name: \"%s\"",
+ conf_display->disp_visual);
+ return FALSE;
+ }
+ } else {
+ displayp->defaultVisual = -1;
+ }
+
+ /*
+ * now hook in the modes
+ */
+ modep = conf_display->disp_mode_lst;
+ while(modep) {
+ count++;
+ modep = (XF86ModePtr)modep->list.next;
+ }
+ displayp->modes = xnfalloc((count+1) * sizeof(char*));
+ modep = conf_display->disp_mode_lst;
+ count = 0;
+ while(modep) {
+ displayp->modes[count] = modep->mode_name;
+ count++;
+ modep = (XF86ModePtr)modep->list.next;
+ }
+ displayp->modes[count] = NULL;
+
+ return TRUE;
+}
+
+static Bool
+configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
+{
+ int i;
+
+ if (!conf_device) {
+ return FALSE;
+ }
+
+ if (active)
+ xf86Msg(X_CONFIG, "| |-->Device \"%s\"\n",
+ conf_device->dev_identifier);
+ else
+ xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
+ conf_device->dev_identifier);
+
+ devicep->identifier = conf_device->dev_identifier;
+ devicep->vendor = conf_device->dev_vendor;
+ devicep->board = conf_device->dev_board;
+ devicep->chipset = conf_device->dev_chipset;
+ devicep->ramdac = conf_device->dev_ramdac;
+ devicep->driver = conf_device->dev_driver;
+ devicep->active = active;
+ devicep->videoRam = conf_device->dev_videoram;
+ devicep->BiosBase = conf_device->dev_bios_base;
+ devicep->MemBase = conf_device->dev_mem_base;
+ devicep->IOBase = conf_device->dev_io_base;
+ devicep->clockchip = conf_device->dev_clockchip;
+ devicep->busID = conf_device->dev_busid;
+ devicep->textClockFreq = conf_device->dev_textclockfreq;
+ devicep->chipID = conf_device->dev_chipid;
+ devicep->chipRev = conf_device->dev_chiprev;
+ devicep->options = conf_device->dev_option_lst;
+ devicep->irq = conf_device->dev_irq;
+ devicep->screen = conf_device->dev_screen;
+
+ for (i = 0; i < MAXDACSPEEDS; i++) {
+ if (i < CONF_MAXDACSPEEDS)
+ devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i];
+ else
+ devicep->dacSpeeds[i] = 0;
+ }
+ devicep->numclocks = conf_device->dev_clocks;
+ if (devicep->numclocks > MAXCLOCKS)
+ devicep->numclocks = MAXCLOCKS;
+ for (i = 0; i < devicep->numclocks; i++) {
+ devicep->clock[i] = conf_device->dev_clock[i];
+ }
+ devicep->claimed = FALSE;
+
+ return TRUE;
+}
+
+#ifdef XF86DRI
+static void
+configDRI(XF86ConfDRIPtr drip)
+{
+ struct group *grp;
+
+ xf86ConfigDRI.group = -1;
+ xf86ConfigDRI.mode = 0;
+
+ if (drip) {
+ if (drip->dri_group_name) {
+ if ((grp = getgrnam(drip->dri_group_name)))
+ xf86ConfigDRI.group = grp->gr_gid;
+ } else {
+ if (drip->dri_group >= 0)
+ xf86ConfigDRI.group = drip->dri_group;
+ }
+ xf86ConfigDRI.mode = drip->dri_mode;
+ }
+}
+#endif
+
+static void
+configExtensions(XF86ConfExtensionsPtr conf_ext)
+{
+ XF86OptionPtr o;
+
+ if (conf_ext && conf_ext->ext_option_lst) {
+ for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) {
+ char *name = xf86OptionName(o);
+ char *val = xf86OptionValue(o);
+ char *n;
+ Bool enable = TRUE;
+
+ /* Handle "No<ExtensionName>" */
+ n = xf86NormalizeName(name);
+ if (strncmp(n, "no", 2) == 0) {
+ name += 2;
+ enable = FALSE;
+ }
+
+ if (!val ||
+ xf86NameCmp(val, "enable") == 0 ||
+ xf86NameCmp(val, "enabled") == 0 ||
+ xf86NameCmp(val, "on") == 0 ||
+ xf86NameCmp(val, "1") == 0 ||
+ xf86NameCmp(val, "yes") == 0 ||
+ xf86NameCmp(val, "true") == 0) {
+ /* NOTHING NEEDED -- enabling is handled below */
+ } else if (xf86NameCmp(val, "disable") == 0 ||
+ xf86NameCmp(val, "disabled") == 0 ||
+ xf86NameCmp(val, "off") == 0 ||
+ xf86NameCmp(val, "0") == 0 ||
+ xf86NameCmp(val, "no") == 0 ||
+ xf86NameCmp(val, "false") == 0) {
+ enable = !enable;
+ } else {
+ xf86Msg(X_WARNING, "Ignoring unrecognized value \"%s\"\n", val);
+ free(n);
+ continue;
+ }
+
+ if (EnableDisableExtension(name, enable)) {
+ xf86Msg(X_CONFIG, "Extension \"%s\" is %s\n",
+ name, enable ? "enabled" : "disabled");
+ } else {
+ xf86Msg(X_WARNING, "Ignoring unrecognized extension \"%s\"\n",
+ name);
+ }
+ free(n);
+ }
+ }
+}
+
+static Bool
+configInput(InputInfoPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
+{
+ xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier);
+ inputp->name = conf_input->inp_identifier;
+ inputp->driver = conf_input->inp_driver;
+ inputp->options = conf_input->inp_option_lst;
+ inputp->attrs = NULL;
+
+ return TRUE;
+}
+
+static Bool
+modeIsPresent(DisplayModePtr mode, MonPtr monitorp)
+{
+ DisplayModePtr knownmodes = monitorp->Modes;
+
+ /* all I can think of is a linear search... */
+ while(knownmodes != NULL)
+ {
+ if(!strcmp(mode->name, knownmodes->name) &&
+ !(knownmodes->type & M_T_DEFAULT))
+ return TRUE;
+ knownmodes = knownmodes->next;
+ }
+ return FALSE;
+}
+
+static Bool
+addDefaultModes(MonPtr monitorp)
+{
+ DisplayModePtr mode;
+ DisplayModePtr last = monitorp->Last;
+ int i = 0;
+
+ for (i = 0; i < xf86NumDefaultModes; i++)
+ {
+ mode = xf86DuplicateMode(&xf86DefaultModes[i]);
+ if (!modeIsPresent(mode, monitorp))
+ {
+ monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode);
+ last = mode;
+ } else {
+ free(mode);
+ }
+ }
+ monitorp->Last = last;
+
+ return TRUE;
+}
+
+static void
+checkInput(serverLayoutPtr layout, Bool implicit_layout) {
+ checkCoreInputDevices(layout, implicit_layout);
+
+ /* Unless we're forcing input devices, disable mouse/kbd devices in the
+ * config. Otherwise the same physical device is added multiple times,
+ * leading to duplicate events.
+ */
+ if (!xf86Info.forceInputDevices && layout->inputs)
+ {
+ InputInfoPtr *dev = layout->inputs;
+ BOOL warned = FALSE;
+
+ while(*dev)
+ {
+ if (strcmp((*dev)->driver, "kbd") == 0 ||
+ strcmp((*dev)->driver, "mouse") == 0 ||
+ strcmp((*dev)->driver, "vmmouse") == 0)
+ {
+ InputInfoPtr *current;
+ if (!warned)
+ {
+ xf86Msg(X_WARNING, "Hotplugging is on, devices using "
+ "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n");
+ warned = TRUE;
+ }
+
+ xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->name);
+
+ current = dev;
+ free(*dev);
+
+ do {
+ *current = *(current + 1);
+ current++;
+ } while(*current);
+ } else
+ dev++;
+ }
+ }
+}
+
+/*
+ * load the config file and fill the global data structure
+ */
+ConfigStatus
+xf86HandleConfigFile(Bool autoconfig)
+{
+ const char *filename, *dirname, *sysdirname;
+ char *filesearch, *dirsearch;
+ MessageType filefrom = X_DEFAULT;
+ MessageType dirfrom = X_DEFAULT;
+ char *scanptr;
+ Bool singlecard = 0;
+ Bool implicit_layout = FALSE;
+
+ if (!autoconfig) {
+ if (getuid() == 0) {
+ filesearch = ROOT_CONFIGPATH;
+ dirsearch = ROOT_CONFIGDIRPATH;
+ } else {
+ filesearch = USER_CONFIGPATH;
+ dirsearch = USER_CONFIGDIRPATH;
+ }
+
+ if (xf86ConfigFile)
+ filefrom = X_CMDLINE;
+ if (xf86ConfigDir)
+ dirfrom = X_CMDLINE;
+
+ xf86initConfigFiles();
+ sysdirname = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL,
+ PROJECTROOT);
+ dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT);
+ filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT);
+ if (filename) {
+ xf86MsgVerb(filefrom, 0, "Using config file: \"%s\"\n", filename);
+ xf86ConfigFile = xnfstrdup(filename);
+ } else {
+ if (xf86ConfigFile)
+ xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
+ xf86ConfigFile);
+ }
+ if (dirname) {
+ xf86MsgVerb(dirfrom, 0, "Using config directory: \"%s\"\n",
+ dirname);
+ xf86ConfigDir = xnfstrdup(dirname);
+ } else {
+ if (xf86ConfigDir)
+ xf86Msg(X_ERROR,
+ "Unable to locate/open config directory: \"%s\"\n",
+ xf86ConfigDir);
+ }
+ if (sysdirname)
+ xf86MsgVerb(X_DEFAULT, 0, "Using system config directory \"%s\"\n",
+ sysdirname);
+ if (!filename && !dirname && !sysdirname)
+ return CONFIG_NOFILE;
+ }
+
+ if ((xf86configptr = xf86readConfigFile ()) == NULL) {
+ xf86Msg(X_ERROR, "Problem parsing the config file\n");
+ return CONFIG_PARSE_ERROR;
+ }
+ xf86closeConfigFile ();
+
+ /* Initialise a few things. */
+
+ /*
+ * now we convert part of the information contained in the parser
+ * structures into our own structures.
+ * The important part here is to figure out which Screen Sections
+ * in the XF86Config file are active so that we can piece together
+ * the modes that we need later down the road.
+ * And while we are at it, we'll decode the rest of the stuff as well
+ */
+
+ /* First check if a layout section is present, and if it is valid. */
+
+ if (xf86configptr->conf_layout_lst == NULL || xf86ScreenName != NULL) {
+ if (xf86ScreenName == NULL) {
+ xf86Msg(X_DEFAULT,
+ "No Layout section. Using the first Screen section.\n");
+ }
+ if (!configImpliedLayout(&xf86ConfigLayout,
+ xf86configptr->conf_screen_lst,
+ xf86configptr)) {
+ xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
+ return CONFIG_PARSE_ERROR;
+ }
+ implicit_layout = TRUE;
+ } else {
+ if (xf86configptr->conf_flags != NULL) {
+ char *dfltlayout = NULL;
+ pointer optlist = xf86configptr->conf_flags->flg_option_lst;
+
+ if (optlist && xf86FindOption(optlist, "defaultserverlayout"))
+ dfltlayout = xf86SetStrOption(optlist, "defaultserverlayout", NULL);
+ if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
+ dfltlayout)) {
+ xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
+ return CONFIG_PARSE_ERROR;
+ }
+ } else {
+ if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
+ NULL)) {
+ xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
+ return CONFIG_PARSE_ERROR;
+ }
+ }
+ }
+
+ xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions);
+
+ if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) {
+ ; /* IsolateDevice specified; overrides SingleCard */
+ } else {
+ xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard);
+ if (singlecard)
+ scanptr = xf86ConfigLayout.screens->screen->device->busID;
+ }
+ if (scanptr) {
+ if (strncmp(scanptr, "PCI:", 4) != 0) {
+ xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n"
+ "\tIgnoring IsolateDevice option.\n");
+ } else
+ xf86PciIsolateDevice(scanptr);
+ }
+
+ /* Now process everything else */
+ if (!configServerFlags(xf86configptr->conf_flags,xf86ConfigLayout.options)){
+ ErrorF ("Problem when converting the config data structures\n");
+ return CONFIG_PARSE_ERROR;
+ }
+
+ configFiles(xf86configptr->conf_files);
+ configExtensions(xf86configptr->conf_extensions);
+#ifdef XF86DRI
+ configDRI(xf86configptr->conf_dri);
+#endif
+
+ checkInput(&xf86ConfigLayout, implicit_layout);
+
+ /*
+ * Handle some command line options that can override some of the
+ * ServerFlags settings.
+ */
+#ifdef XF86VIDMODE
+ if (xf86VidModeDisabled)
+ xf86Info.vidModeEnabled = FALSE;
+ if (xf86VidModeAllowNonLocal)
+ xf86Info.vidModeAllowNonLocal = TRUE;
+#endif
+
+ if (xf86AllowMouseOpenFail)
+ xf86Info.allowMouseOpenFail = TRUE;
+
+ return CONFIG_OK;
+}
+
+Bool
+xf86PathIsSafe(const char *path)
+{
+ return (xf86pathIsSafe(path) != 0);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Configure.c b/xorg-server/hw/xfree86/common/xf86Configure.c
index 975266943..ba0628ffd 100644
--- a/xorg-server/hw/xfree86/common/xf86Configure.c
+++ b/xorg-server/hw/xfree86/common/xf86Configure.c
@@ -1,755 +1,755 @@
-/*
- * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
- *
- * 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 Alan Hourihane not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Alan Hourihane makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL ALAN HOURIHANE 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.
- *
- * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86Config.h"
-#include "xf86_OSlib.h"
-#include "xf86Priv.h"
-#define IN_XSERVER
-#include "Configint.h"
-#include "xf86DDC.h"
-#include "xf86pciBus.h"
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
-#include "xf86Bus.h"
-#include "xf86Sbus.h"
-#endif
-#include "misc.h"
-
-typedef struct _DevToConfig {
- GDevRec GDev;
- struct pci_device * pVideo;
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
- sbusDevicePtr sVideo;
-#endif
- int iDriver;
-} DevToConfigRec, *DevToConfigPtr;
-
-static DevToConfigPtr DevToConfig = NULL;
-static int nDevToConfig = 0, CurrentDriver;
-
-xf86MonPtr ConfiguredMonitor;
-Bool xf86DoConfigurePass1 = TRUE;
-static Bool foundMouse = FALSE;
-
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
-static char *DFLT_MOUSE_DEV = "/dev/sysmouse";
-static char *DFLT_MOUSE_PROTO = "auto";
-#elif defined(linux)
-static char DFLT_MOUSE_DEV[] = "/dev/input/mice";
-static char DFLT_MOUSE_PROTO[] = "auto";
-#elif defined(WSCONS_SUPPORT)
-static char *DFLT_MOUSE_DEV = "/dev/wsmouse";
-static char *DFLT_MOUSE_PROTO = "wsmouse";
-#else
-static char *DFLT_MOUSE_DEV = "/dev/mouse";
-static char *DFLT_MOUSE_PROTO = "auto";
-#endif
-
-/*
- * This is called by the driver, either through xf86Match???Instances() or
- * directly. We allocate a GDevRec and fill it in as much as we can, letting
- * the caller fill in the rest and/or change it as it sees fit.
- */
-GDevPtr
-xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int chipset)
-{
- int ret, i, j;
-
- if (!xf86DoConfigure || !xf86DoConfigurePass1)
- return NULL;
-
- /* Check for duplicates */
- for (i = 0; i < nDevToConfig; i++) {
- switch (bus) {
- case BUS_PCI:
- ret = xf86PciConfigure(busData, DevToConfig[i].pVideo);
- break;
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
- case BUS_SBUS:
- ret = xf86SbusConfigure(busData, DevToConfig[i].sVideo);
- break;
-#endif
- default:
- return NULL;
- }
- if (ret == 0)
- goto out;
- }
-
- /* Allocate new structure occurrence */
- i = nDevToConfig++;
- DevToConfig =
- xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec));
- memset(DevToConfig + i, 0, sizeof(DevToConfigRec));
-
- DevToConfig[i].GDev.chipID =
- DevToConfig[i].GDev.chipRev = DevToConfig[i].GDev.irq = -1;
-
- DevToConfig[i].iDriver = CurrentDriver;
-
- /* Fill in what we know, converting the driver name to lower case */
- DevToConfig[i].GDev.driver = xnfalloc(strlen(driver) + 1);
- for (j = 0; (DevToConfig[i].GDev.driver[j] = tolower(driver[j])); j++);
-
- switch (bus) {
- case BUS_PCI:
- xf86PciConfigureNewDev(busData, DevToConfig[i].pVideo,
- &DevToConfig[i].GDev, &chipset);
- break;
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
- case BUS_SBUS:
- xf86SbusConfigureNewDev(busData, DevToConfig[i].sVideo,
- &DevToConfig[i].GDev);
- break;
-#endif
- default:
- break;
- }
-
- /* Get driver's available options */
- if (xf86DriverList[CurrentDriver]->AvailableOptions)
- DevToConfig[i].GDev.options = (OptionInfoPtr)
- (*xf86DriverList[CurrentDriver]->AvailableOptions)(chipset,
- bus);
-
- return &DevToConfig[i].GDev;
-
-out:
- return NULL;
-}
-
-static XF86ConfInputPtr
-configureInputSection (void)
-{
- XF86ConfInputPtr mouse = NULL;
- parsePrologue (XF86ConfInputPtr, XF86ConfInputRec)
-
- ptr->inp_identifier = "Keyboard0";
- ptr->inp_driver = "kbd";
- ptr->list.next = NULL;
-
- /* Crude mechanism to auto-detect mouse (os dependent) */
- {
- int fd;
-
- fd = open(DFLT_MOUSE_DEV, 0);
- if (fd != -1) {
- foundMouse = TRUE;
- close(fd);
- }
- }
-
- mouse = calloc(1, sizeof(XF86ConfInputRec));
- mouse->inp_identifier = "Mouse0";
- mouse->inp_driver = "mouse";
- mouse->inp_option_lst =
- xf86addNewOption(mouse->inp_option_lst, strdup("Protocol"),
- strdup(DFLT_MOUSE_PROTO));
- mouse->inp_option_lst =
- xf86addNewOption(mouse->inp_option_lst, strdup("Device"),
- strdup(DFLT_MOUSE_DEV));
- mouse->inp_option_lst =
- xf86addNewOption(mouse->inp_option_lst, strdup("ZAxisMapping"),
- strdup("4 5 6 7"));
- ptr = (XF86ConfInputPtr)xf86addListItem((glp)ptr, (glp)mouse);
- return ptr;
-}
-
-static XF86ConfScreenPtr
-configureScreenSection (int screennum)
-{
- int i;
- int depths[] = { 1, 4, 8, 15, 16, 24/*, 32*/ };
- parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec)
-
- XNFasprintf(&ptr->scrn_identifier, "Screen%d", screennum);
- XNFasprintf(&ptr->scrn_monitor_str, "Monitor%d", screennum);
- XNFasprintf(&ptr->scrn_device_str, "Card%d", screennum);
-
- for (i=0; i<sizeof(depths)/sizeof(depths[0]); i++)
- {
- XF86ConfDisplayPtr display;
-
- display = calloc(1, sizeof(XF86ConfDisplayRec));
- display->disp_depth = depths[i];
- display->disp_black.red = display->disp_white.red = -1;
- display->disp_black.green = display->disp_white.green = -1;
- display->disp_black.blue = display->disp_white.blue = -1;
- ptr->scrn_display_lst = (XF86ConfDisplayPtr)xf86addListItem(
- (glp)ptr->scrn_display_lst, (glp)display);
- }
-
- return ptr;
-}
-
-static const char*
-optionTypeToString(OptionValueType type)
-{
- switch (type) {
- case OPTV_NONE:
- return "";
- case OPTV_INTEGER:
- return "<i>";
- case OPTV_STRING:
- return "<str>";
- case OPTV_ANYSTR:
- return "[<str>]";
- case OPTV_REAL:
- return "<f>";
- case OPTV_BOOLEAN:
- return "[<bool>]";
- case OPTV_FREQ:
- return "<freq>";
- case OPTV_PERCENT:
- return "<percent>";
- default:
- return "";
- }
-}
-
-static XF86ConfDevicePtr
-configureDeviceSection (int screennum)
-{
- OptionInfoPtr p;
- int i = 0;
- parsePrologue (XF86ConfDevicePtr, XF86ConfDeviceRec)
-
- /* Move device info to parser structure */
- if (asprintf(&ptr->dev_identifier, "Card%d", screennum) == -1)
- ptr->dev_identifier = NULL;
- ptr->dev_chipset = DevToConfig[screennum].GDev.chipset;
- ptr->dev_busid = DevToConfig[screennum].GDev.busID;
- ptr->dev_driver = DevToConfig[screennum].GDev.driver;
- ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac;
- for (i = 0; (i < MAXDACSPEEDS) && (i < CONF_MAXDACSPEEDS); i++)
- ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i];
- ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam;
- ptr->dev_textclockfreq = DevToConfig[screennum].GDev.textClockFreq;
- ptr->dev_bios_base = DevToConfig[screennum].GDev.BiosBase;
- ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase;
- ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase;
- ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip;
- for (i = 0; (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks); i++)
- ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i];
- ptr->dev_clocks = i;
- ptr->dev_chipid = DevToConfig[screennum].GDev.chipID;
- ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev;
- ptr->dev_irq = DevToConfig[screennum].GDev.irq;
-
- /* Make sure older drivers don't segv */
- if (DevToConfig[screennum].GDev.options) {
- /* Fill in the available driver options for people to use */
- const char *descrip =
- " ### Available Driver options are:-\n"
- " ### Values: <i>: integer, <f>: float, "
- "<bool>: \"True\"/\"False\",\n"
- " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\",\n"
- " ### <percent>: \"<f>%\"\n"
- " ### [arg]: arg optional\n";
- ptr->dev_comment = strdup(descrip);
- if (ptr->dev_comment) {
- for (p = DevToConfig[screennum].GDev.options;
- p->name != NULL; p++) {
- char *p_e;
- const char *prefix = " #Option ";
- const char *middle = " \t# ";
- const char *suffix = "\n";
- const char *opttype = optionTypeToString(p->type);
- char *optname;
- int len = strlen(ptr->dev_comment) + strlen(prefix) +
- strlen(middle) + strlen(suffix) + 1;
-
- if (asprintf(&optname, "\"%s\"", p->name) == -1)
- break;
-
- len += max(20, strlen(optname));
- len += strlen(opttype);
-
- ptr->dev_comment = realloc(ptr->dev_comment, len);
- if (!ptr->dev_comment)
- break;
- p_e = ptr->dev_comment + strlen(ptr->dev_comment);
- sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle,
- opttype, suffix);
- free(optname);
- }
- }
- }
-
- return ptr;
-}
-
-static XF86ConfLayoutPtr
-configureLayoutSection (void)
-{
- int scrnum = 0;
- parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
-
- ptr->lay_identifier = "X.org Configured";
-
- {
- XF86ConfInputrefPtr iptr;
-
- iptr = malloc (sizeof (XF86ConfInputrefRec));
- iptr->list.next = NULL;
- iptr->iref_option_lst = NULL;
- iptr->iref_inputdev_str = "Mouse0";
- iptr->iref_option_lst =
- xf86addNewOption (iptr->iref_option_lst, strdup("CorePointer"), NULL);
- ptr->lay_input_lst = (XF86ConfInputrefPtr)
- xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
- }
-
- {
- XF86ConfInputrefPtr iptr;
-
- iptr = malloc (sizeof (XF86ConfInputrefRec));
- iptr->list.next = NULL;
- iptr->iref_option_lst = NULL;
- iptr->iref_inputdev_str = "Keyboard0";
- iptr->iref_option_lst =
- xf86addNewOption (iptr->iref_option_lst, strdup("CoreKeyboard"), NULL);
- ptr->lay_input_lst = (XF86ConfInputrefPtr)
- xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
- }
-
- for (scrnum = 0; scrnum < nDevToConfig; scrnum++) {
- XF86ConfAdjacencyPtr aptr;
-
- aptr = malloc (sizeof (XF86ConfAdjacencyRec));
- aptr->list.next = NULL;
- aptr->adj_x = 0;
- aptr->adj_y = 0;
- aptr->adj_scrnum = scrnum;
- XNFasprintf(&aptr->adj_screen_str, "Screen%d", scrnum);
- if (scrnum == 0) {
- aptr->adj_where = CONF_ADJ_ABSOLUTE;
- aptr->adj_refscreen = NULL;
- }
- else {
- aptr->adj_where = CONF_ADJ_RIGHTOF;
- XNFasprintf(&aptr->adj_refscreen, "Screen%d", scrnum - 1);
- }
- ptr->lay_adjacency_lst =
- (XF86ConfAdjacencyPtr)xf86addListItem((glp)ptr->lay_adjacency_lst,
- (glp)aptr);
- }
-
- return ptr;
-}
-
-static XF86ConfFlagsPtr
-configureFlagsSection (void)
-{
- parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
-
- return ptr;
-}
-
-static XF86ConfModulePtr
-configureModuleSection (void)
-{
- char **elist, **el;
- /* Find the list of extension & font modules. */
- const char *esubdirs[] = {
- "extensions",
- "fonts",
- NULL
- };
- parsePrologue (XF86ConfModulePtr, XF86ConfModuleRec)
-
- elist = LoaderListDirs(esubdirs, NULL);
- if (elist) {
- for (el = elist; *el; el++) {
- XF86LoadPtr module;
-
- module = calloc(1, sizeof(XF86LoadRec));
- module->load_name = *el;
- ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem(
- (glp)ptr->mod_load_lst, (glp)module);
- }
- free(elist);
- }
-
- return ptr;
-}
-
-static XF86ConfFilesPtr
-configureFilesSection (void)
-{
- parsePrologue (XF86ConfFilesPtr, XF86ConfFilesRec)
-
- if (xf86ModulePath)
- ptr->file_modulepath = strdup(xf86ModulePath);
- if (defaultFontPath)
- ptr->file_fontpath = strdup(defaultFontPath);
-
- return ptr;
-}
-
-static XF86ConfMonitorPtr
-configureMonitorSection (int screennum)
-{
- parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
-
- XNFasprintf(&ptr->mon_identifier, "Monitor%d", screennum);
- ptr->mon_vendor = strdup("Monitor Vendor");
- ptr->mon_modelname = strdup("Monitor Model");
-
- return ptr;
-}
-
-/* Initialize Configure Monitor from Detailed Timing Block */
-static void handle_detailed_input(struct detailed_monitor_section *det_mon,
- void *data)
-{
- XF86ConfMonitorPtr ptr = (XF86ConfMonitorPtr) data;
-
- switch (det_mon->type) {
- case DS_NAME:
- ptr->mon_modelname = realloc(ptr->mon_modelname,
- strlen((char*)(det_mon->section.name)) +
- 1);
- strcpy(ptr->mon_modelname,
- (char*)(det_mon->section.name));
- break;
- case DS_RANGES:
- ptr->mon_hsync[ptr->mon_n_hsync].lo =
- det_mon->section.ranges.min_h;
- ptr->mon_hsync[ptr->mon_n_hsync].hi =
- det_mon->section.ranges.max_h;
- ptr->mon_n_vrefresh = 1;
- ptr->mon_vrefresh[ptr->mon_n_hsync].lo =
- det_mon->section.ranges.min_v;
- ptr->mon_vrefresh[ptr->mon_n_hsync].hi =
- det_mon->section.ranges.max_v;
- ptr->mon_n_hsync++;
- default:
- break;
- }
-}
-
-static XF86ConfMonitorPtr
-configureDDCMonitorSection (int screennum)
-{
- int len, mon_width, mon_height;
-#define displaySizeMaxLen 80
- char displaySize_string[displaySizeMaxLen];
- int displaySizeLen;
-
- parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
-
- XNFasprintf(&ptr->mon_identifier, "Monitor%d", screennum);
- ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name);
- XNFasprintf(&ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id);
-
- /* features in centimetres, we want millimetres */
- mon_width = 10 * ConfiguredMonitor->features.hsize ;
- mon_height = 10 * ConfiguredMonitor->features.vsize ;
-
-#ifdef CONFIGURE_DISPLAYSIZE
- ptr->mon_width = mon_width;
- ptr->mon_height = mon_height;
-#else
- if (mon_width && mon_height) {
- /* when values available add DisplaySize option AS A COMMENT */
-
- displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen,
- "\t#DisplaySize\t%5d %5d\t# mm\n",
- mon_width, mon_height);
-
- if (displaySizeLen>0 && displaySizeLen<displaySizeMaxLen) {
- if (ptr->mon_comment) {
- len = strlen(ptr->mon_comment);
- } else {
- len = 0;
- }
- if ((ptr->mon_comment =
- realloc(ptr->mon_comment, len + strlen(displaySize_string) + 1))) {
- strcpy(ptr->mon_comment + len, displaySize_string);
- }
- }
- }
-#endif /* def CONFIGURE_DISPLAYSIZE */
-
- xf86ForEachDetailedBlock(ConfiguredMonitor, handle_detailed_input,
- ptr);
-
- if (ConfiguredMonitor->features.dpms) {
- ptr->mon_option_lst = xf86addNewOption(ptr->mon_option_lst, strdup("DPMS"), NULL);
- }
-
- return ptr;
-}
-
-void
-DoConfigure(void)
-{
- int i,j, screennum = -1;
- char *home = NULL;
- char filename[PATH_MAX];
- char *addslash = "";
- XF86ConfigPtr xf86config = NULL;
- char **vlist, **vl;
- int *dev2screen;
-
- vlist = xf86DriverlistFromCompile();
-
- if (!vlist) {
- ErrorF("Missing output drivers. Configuration failed.\n");
- goto bail;
- }
-
- ErrorF("List of video drivers:\n");
- for (vl = vlist; *vl; vl++)
- ErrorF("\t%s\n", *vl);
-
- /* Load all the drivers that were found. */
- xf86LoadModules(vlist, NULL);
-
- free(vlist);
-
- for (i = 0; i < xf86NumDrivers; i++) {
- xorgHWFlags flags;
- if (!xf86DriverList[i]->driverFunc
- || !xf86DriverList[i]->driverFunc(NULL,
- GET_REQUIRED_HW_INTERFACES,
- &flags)
- || NEED_IO_ENABLED(flags)) {
- xorgHWAccess = TRUE;
- break;
- }
- }
- /* Enable full I/O access */
- if (xorgHWAccess) {
- if(!xf86EnableIO())
- /* oops, we have failed */
- xorgHWAccess = FALSE;
- }
-
- /* Create XF86Config file structure */
- xf86config = calloc(1, sizeof(XF86ConfigRec));
-
- /* Call all of the probe functions, reporting the results. */
- for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) {
- xorgHWFlags flags;
- Bool found_screen;
- DriverRec * const drv = xf86DriverList[CurrentDriver];
-
- if (!xorgHWAccess) {
- if (!drv->driverFunc
- || !drv->driverFunc( NULL, GET_REQUIRED_HW_INTERFACES, &flags )
- || NEED_IO_ENABLED(flags))
- continue;
- }
-
- found_screen = xf86CallDriverProbe( drv, TRUE );
- if ( found_screen && drv->Identify ) {
- (*drv->Identify)(0);
- }
- }
-
- if (nDevToConfig <= 0) {
- ErrorF("No devices to configure. Configuration failed.\n");
- goto bail;
- }
-
- /* Add device, monitor and screen sections for detected devices */
- for (screennum = 0; screennum < nDevToConfig; screennum++) {
- XF86ConfDevicePtr DevicePtr;
- XF86ConfMonitorPtr MonitorPtr;
- XF86ConfScreenPtr ScreenPtr;
-
- DevicePtr = configureDeviceSection(screennum);
- xf86config->conf_device_lst = (XF86ConfDevicePtr)xf86addListItem(
- (glp)xf86config->conf_device_lst, (glp)DevicePtr);
- MonitorPtr = configureMonitorSection(screennum);
- xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
- (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
- ScreenPtr = configureScreenSection(screennum);
- xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
- (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
- }
-
- xf86config->conf_files = configureFilesSection();
- xf86config->conf_modules = configureModuleSection();
- xf86config->conf_flags = configureFlagsSection();
- xf86config->conf_videoadaptor_lst = NULL;
- xf86config->conf_modes_lst = NULL;
- xf86config->conf_vendor_lst = NULL;
- xf86config->conf_dri = NULL;
- xf86config->conf_input_lst = configureInputSection();
- xf86config->conf_layout_lst = configureLayoutSection();
-
- home = getenv("HOME");
- if ((home == NULL) || (home[0] == '\0')) {
- home = "/";
- } else {
- /* Determine if trailing slash is present or needed */
- int l = strlen(home);
-
- if (home[l-1] != '/') {
- addslash = "/";
- }
- }
-
- snprintf(filename, sizeof(filename), "%s%s" XF86CONFIGFILE ".new",
- home, addslash);
-
- if (xf86writeConfigFile(filename, xf86config) == 0) {
- xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
- filename, strerror(errno));
- goto bail;
- }
-
- xf86DoConfigurePass1 = FALSE;
- /* Try to get DDC information filled in */
- xf86ConfigFile = filename;
- if (xf86HandleConfigFile(FALSE) != CONFIG_OK) {
- goto bail;
- }
-
- xf86DoConfigurePass1 = FALSE;
-
- dev2screen = xnfcalloc(1,xf86NumDrivers*sizeof(int));
-
- {
- Bool *driverProbed = xnfcalloc(1,xf86NumDrivers*sizeof(Bool));
- for (screennum = 0; screennum < nDevToConfig; screennum++) {
- int k,l,n,oldNumScreens;
-
- i = DevToConfig[screennum].iDriver;
-
- if (driverProbed[i]) continue;
- driverProbed[i] = TRUE;
-
- oldNumScreens = xf86NumScreens;
-
- xf86CallDriverProbe( xf86DriverList[i], FALSE );
-
- /* reorder */
- k = screennum > 0 ? screennum : 1;
- for (l = oldNumScreens; l < xf86NumScreens; l++) {
- /* is screen primary? */
- Bool primary = FALSE;
- for (n = 0; n<xf86Screens[l]->numEntities; n++) {
- if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) {
- dev2screen[0] = l;
- primary = TRUE;
- break;
- }
- }
- if (primary) continue;
- /* not primary: assign it to next device of same driver */
- /*
- * NOTE: we assume that devices in DevToConfig
- * and xf86Screens[] have the same order except
- * for the primary device which always comes first.
- */
- for (; k < nDevToConfig; k++) {
- if (DevToConfig[k].iDriver == i) {
- dev2screen[k++] = l;
- break;
- }
- }
- }
- }
- free(driverProbed);
- }
-
-
- if (nDevToConfig != xf86NumScreens) {
- ErrorF("Number of created screens does not match number of detected"
- " devices.\n Configuration failed.\n");
- goto bail;
- }
-
- xf86PostProbe();
-
- for (j = 0; j < xf86NumScreens; j++) {
- xf86Screens[j]->scrnIndex = j;
- }
-
- xf86freeMonitorList(xf86config->conf_monitor_lst);
- xf86config->conf_monitor_lst = NULL;
- xf86freeScreenList(xf86config->conf_screen_lst);
- xf86config->conf_screen_lst = NULL;
- for (j = 0; j < xf86NumScreens; j++) {
- XF86ConfMonitorPtr MonitorPtr;
- XF86ConfScreenPtr ScreenPtr;
-
- ConfiguredMonitor = NULL;
-
- if ((*xf86Screens[dev2screen[j]]->PreInit)(xf86Screens[dev2screen[j]],
- PROBE_DETECT) &&
- ConfiguredMonitor) {
- MonitorPtr = configureDDCMonitorSection(j);
- } else {
- MonitorPtr = configureMonitorSection(j);
- }
- ScreenPtr = configureScreenSection(j);
- xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
- (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
- xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
- (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
- }
-
- if (xf86writeConfigFile(filename, xf86config) == 0) {
- xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
- filename, strerror(errno));
- goto bail;
- }
-
- ErrorF("\n");
-
- if (!foundMouse) {
- ErrorF("\n"__XSERVERNAME__" is not able to detect your mouse.\n"
- "Edit the file and correct the Device.\n");
- } else {
- ErrorF("\n"__XSERVERNAME__" detected your mouse at device %s.\n"
- "Please check your config if the mouse is still not\n"
- "operational, as by default "__XSERVERNAME__
- " tries to autodetect\n"
- "the protocol.\n",DFLT_MOUSE_DEV);
- }
-
- if (xf86NumScreens > 1) {
- ErrorF("\n"__XSERVERNAME__
- " has configured a multihead system, please check your config.\n");
- }
-
- ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE ,filename);
- ErrorF("To test the server, run 'X -config %s'\n\n", filename);
-
-bail:
- OsCleanup(TRUE);
- AbortDDX();
- fflush(stderr);
- exit(0);
-}
+/*
+ * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
+ *
+ * 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 Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ *
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86Config.h"
+#include "xf86_OSlib.h"
+#include "xf86Priv.h"
+#define IN_XSERVER
+#include "Configint.h"
+#include "xf86DDC.h"
+#include "xf86pciBus.h"
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+#include "xf86Bus.h"
+#include "xf86Sbus.h"
+#endif
+#include "misc.h"
+
+typedef struct _DevToConfig {
+ GDevRec GDev;
+ struct pci_device * pVideo;
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+ sbusDevicePtr sVideo;
+#endif
+ int iDriver;
+} DevToConfigRec, *DevToConfigPtr;
+
+static DevToConfigPtr DevToConfig = NULL;
+static int nDevToConfig = 0, CurrentDriver;
+
+xf86MonPtr ConfiguredMonitor;
+Bool xf86DoConfigurePass1 = TRUE;
+static Bool foundMouse = FALSE;
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+static char *DFLT_MOUSE_DEV = "/dev/sysmouse";
+static char *DFLT_MOUSE_PROTO = "auto";
+#elif defined(linux)
+static char DFLT_MOUSE_DEV[] = "/dev/input/mice";
+static char DFLT_MOUSE_PROTO[] = "auto";
+#elif defined(WSCONS_SUPPORT)
+static char *DFLT_MOUSE_DEV = "/dev/wsmouse";
+static char *DFLT_MOUSE_PROTO = "wsmouse";
+#else
+static char *DFLT_MOUSE_DEV = "/dev/mouse";
+static char *DFLT_MOUSE_PROTO = "auto";
+#endif
+
+/*
+ * This is called by the driver, either through xf86Match???Instances() or
+ * directly. We allocate a GDevRec and fill it in as much as we can, letting
+ * the caller fill in the rest and/or change it as it sees fit.
+ */
+GDevPtr
+xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int chipset)
+{
+ int ret, i, j;
+
+ if (!xf86DoConfigure || !xf86DoConfigurePass1)
+ return NULL;
+
+ /* Check for duplicates */
+ for (i = 0; i < nDevToConfig; i++) {
+ switch (bus) {
+ case BUS_PCI:
+ ret = xf86PciConfigure(busData, DevToConfig[i].pVideo);
+ break;
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+ case BUS_SBUS:
+ ret = xf86SbusConfigure(busData, DevToConfig[i].sVideo);
+ break;
+#endif
+ default:
+ return NULL;
+ }
+ if (ret == 0)
+ goto out;
+ }
+
+ /* Allocate new structure occurrence */
+ i = nDevToConfig++;
+ DevToConfig =
+ xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec));
+ memset(DevToConfig + i, 0, sizeof(DevToConfigRec));
+
+ DevToConfig[i].GDev.chipID =
+ DevToConfig[i].GDev.chipRev = DevToConfig[i].GDev.irq = -1;
+
+ DevToConfig[i].iDriver = CurrentDriver;
+
+ /* Fill in what we know, converting the driver name to lower case */
+ DevToConfig[i].GDev.driver = xnfalloc(strlen(driver) + 1);
+ for (j = 0; (DevToConfig[i].GDev.driver[j] = tolower(driver[j])); j++);
+
+ switch (bus) {
+ case BUS_PCI:
+ xf86PciConfigureNewDev(busData, DevToConfig[i].pVideo,
+ &DevToConfig[i].GDev, &chipset);
+ break;
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+ case BUS_SBUS:
+ xf86SbusConfigureNewDev(busData, DevToConfig[i].sVideo,
+ &DevToConfig[i].GDev);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ /* Get driver's available options */
+ if (xf86DriverList[CurrentDriver]->AvailableOptions)
+ DevToConfig[i].GDev.options = (OptionInfoPtr)
+ (*xf86DriverList[CurrentDriver]->AvailableOptions)(chipset,
+ bus);
+
+ return &DevToConfig[i].GDev;
+
+out:
+ return NULL;
+}
+
+static XF86ConfInputPtr
+configureInputSection (void)
+{
+ XF86ConfInputPtr mouse = NULL;
+ parsePrologue (XF86ConfInputPtr, XF86ConfInputRec)
+
+ ptr->inp_identifier = "Keyboard0";
+ ptr->inp_driver = "kbd";
+ ptr->list.next = NULL;
+
+ /* Crude mechanism to auto-detect mouse (os dependent) */
+ {
+ int fd;
+
+ fd = open(DFLT_MOUSE_DEV, 0);
+ if (fd != -1) {
+ foundMouse = TRUE;
+ close(fd);
+ }
+ }
+
+ mouse = calloc(1, sizeof(XF86ConfInputRec));
+ mouse->inp_identifier = "Mouse0";
+ mouse->inp_driver = "mouse";
+ mouse->inp_option_lst =
+ xf86addNewOption(mouse->inp_option_lst, strdup("Protocol"),
+ strdup(DFLT_MOUSE_PROTO));
+ mouse->inp_option_lst =
+ xf86addNewOption(mouse->inp_option_lst, strdup("Device"),
+ strdup(DFLT_MOUSE_DEV));
+ mouse->inp_option_lst =
+ xf86addNewOption(mouse->inp_option_lst, strdup("ZAxisMapping"),
+ strdup("4 5 6 7"));
+ ptr = (XF86ConfInputPtr)xf86addListItem((glp)ptr, (glp)mouse);
+ return ptr;
+}
+
+static XF86ConfScreenPtr
+configureScreenSection (int screennum)
+{
+ int i;
+ int depths[] = { 1, 4, 8, 15, 16, 24/*, 32*/ };
+ parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec)
+
+ XNFasprintf(&ptr->scrn_identifier, "Screen%d", screennum);
+ XNFasprintf(&ptr->scrn_monitor_str, "Monitor%d", screennum);
+ XNFasprintf(&ptr->scrn_device_str, "Card%d", screennum);
+
+ for (i=0; i<sizeof(depths)/sizeof(depths[0]); i++)
+ {
+ XF86ConfDisplayPtr display;
+
+ display = calloc(1, sizeof(XF86ConfDisplayRec));
+ display->disp_depth = depths[i];
+ display->disp_black.red = display->disp_white.red = -1;
+ display->disp_black.green = display->disp_white.green = -1;
+ display->disp_black.blue = display->disp_white.blue = -1;
+ ptr->scrn_display_lst = (XF86ConfDisplayPtr)xf86addListItem(
+ (glp)ptr->scrn_display_lst, (glp)display);
+ }
+
+ return ptr;
+}
+
+static const char*
+optionTypeToString(OptionValueType type)
+{
+ switch (type) {
+ case OPTV_NONE:
+ return "";
+ case OPTV_INTEGER:
+ return "<i>";
+ case OPTV_STRING:
+ return "<str>";
+ case OPTV_ANYSTR:
+ return "[<str>]";
+ case OPTV_REAL:
+ return "<f>";
+ case OPTV_BOOLEAN:
+ return "[<bool>]";
+ case OPTV_FREQ:
+ return "<freq>";
+ case OPTV_PERCENT:
+ return "<percent>";
+ default:
+ return "";
+ }
+}
+
+static XF86ConfDevicePtr
+configureDeviceSection (int screennum)
+{
+ OptionInfoPtr p;
+ int i = 0;
+ parsePrologue (XF86ConfDevicePtr, XF86ConfDeviceRec)
+
+ /* Move device info to parser structure */
+ if (asprintf(&ptr->dev_identifier, "Card%d", screennum) == -1)
+ ptr->dev_identifier = NULL;
+ ptr->dev_chipset = DevToConfig[screennum].GDev.chipset;
+ ptr->dev_busid = DevToConfig[screennum].GDev.busID;
+ ptr->dev_driver = DevToConfig[screennum].GDev.driver;
+ ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac;
+ for (i = 0; (i < MAXDACSPEEDS) && (i < CONF_MAXDACSPEEDS); i++)
+ ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i];
+ ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam;
+ ptr->dev_textclockfreq = DevToConfig[screennum].GDev.textClockFreq;
+ ptr->dev_bios_base = DevToConfig[screennum].GDev.BiosBase;
+ ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase;
+ ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase;
+ ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip;
+ for (i = 0; (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks); i++)
+ ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i];
+ ptr->dev_clocks = i;
+ ptr->dev_chipid = DevToConfig[screennum].GDev.chipID;
+ ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev;
+ ptr->dev_irq = DevToConfig[screennum].GDev.irq;
+
+ /* Make sure older drivers don't segv */
+ if (DevToConfig[screennum].GDev.options) {
+ /* Fill in the available driver options for people to use */
+ const char *descrip =
+ " ### Available Driver options are:-\n"
+ " ### Values: <i>: integer, <f>: float, "
+ "<bool>: \"True\"/\"False\",\n"
+ " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\",\n"
+ " ### <percent>: \"<f>%\"\n"
+ " ### [arg]: arg optional\n";
+ ptr->dev_comment = strdup(descrip);
+ if (ptr->dev_comment) {
+ for (p = DevToConfig[screennum].GDev.options;
+ p->name != NULL; p++) {
+ char *p_e;
+ const char *prefix = " #Option ";
+ const char *middle = " \t# ";
+ const char *suffix = "\n";
+ const char *opttype = optionTypeToString(p->type);
+ char *optname;
+ int len = strlen(ptr->dev_comment) + strlen(prefix) +
+ strlen(middle) + strlen(suffix) + 1;
+
+ if (asprintf(&optname, "\"%s\"", p->name) == -1)
+ break;
+
+ len += max(20, strlen(optname));
+ len += strlen(opttype);
+
+ ptr->dev_comment = realloc(ptr->dev_comment, len);
+ if (!ptr->dev_comment)
+ break;
+ p_e = ptr->dev_comment + strlen(ptr->dev_comment);
+ sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle,
+ opttype, suffix);
+ free(optname);
+ }
+ }
+ }
+
+ return ptr;
+}
+
+static XF86ConfLayoutPtr
+configureLayoutSection (void)
+{
+ int scrnum = 0;
+ parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
+
+ ptr->lay_identifier = "X.org Configured";
+
+ {
+ XF86ConfInputrefPtr iptr;
+
+ iptr = malloc (sizeof (XF86ConfInputrefRec));
+ iptr->list.next = NULL;
+ iptr->iref_option_lst = NULL;
+ iptr->iref_inputdev_str = "Mouse0";
+ iptr->iref_option_lst =
+ xf86addNewOption (iptr->iref_option_lst, strdup("CorePointer"), NULL);
+ ptr->lay_input_lst = (XF86ConfInputrefPtr)
+ xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
+ }
+
+ {
+ XF86ConfInputrefPtr iptr;
+
+ iptr = malloc (sizeof (XF86ConfInputrefRec));
+ iptr->list.next = NULL;
+ iptr->iref_option_lst = NULL;
+ iptr->iref_inputdev_str = "Keyboard0";
+ iptr->iref_option_lst =
+ xf86addNewOption (iptr->iref_option_lst, strdup("CoreKeyboard"), NULL);
+ ptr->lay_input_lst = (XF86ConfInputrefPtr)
+ xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
+ }
+
+ for (scrnum = 0; scrnum < nDevToConfig; scrnum++) {
+ XF86ConfAdjacencyPtr aptr;
+
+ aptr = malloc (sizeof (XF86ConfAdjacencyRec));
+ aptr->list.next = NULL;
+ aptr->adj_x = 0;
+ aptr->adj_y = 0;
+ aptr->adj_scrnum = scrnum;
+ XNFasprintf(&aptr->adj_screen_str, "Screen%d", scrnum);
+ if (scrnum == 0) {
+ aptr->adj_where = CONF_ADJ_ABSOLUTE;
+ aptr->adj_refscreen = NULL;
+ }
+ else {
+ aptr->adj_where = CONF_ADJ_RIGHTOF;
+ XNFasprintf(&aptr->adj_refscreen, "Screen%d", scrnum - 1);
+ }
+ ptr->lay_adjacency_lst =
+ (XF86ConfAdjacencyPtr)xf86addListItem((glp)ptr->lay_adjacency_lst,
+ (glp)aptr);
+ }
+
+ return ptr;
+}
+
+static XF86ConfFlagsPtr
+configureFlagsSection (void)
+{
+ parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
+
+ return ptr;
+}
+
+static XF86ConfModulePtr
+configureModuleSection (void)
+{
+ char **elist, **el;
+ /* Find the list of extension & font modules. */
+ const char *esubdirs[] = {
+ "extensions",
+ "fonts",
+ NULL
+ };
+ parsePrologue (XF86ConfModulePtr, XF86ConfModuleRec)
+
+ elist = LoaderListDirs(esubdirs, NULL);
+ if (elist) {
+ for (el = elist; *el; el++) {
+ XF86LoadPtr module;
+
+ module = calloc(1, sizeof(XF86LoadRec));
+ module->load_name = *el;
+ ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem(
+ (glp)ptr->mod_load_lst, (glp)module);
+ }
+ free(elist);
+ }
+
+ return ptr;
+}
+
+static XF86ConfFilesPtr
+configureFilesSection (void)
+{
+ parsePrologue (XF86ConfFilesPtr, XF86ConfFilesRec)
+
+ if (xf86ModulePath)
+ ptr->file_modulepath = strdup(xf86ModulePath);
+ if (defaultFontPath)
+ ptr->file_fontpath = strdup(defaultFontPath);
+
+ return ptr;
+}
+
+static XF86ConfMonitorPtr
+configureMonitorSection (int screennum)
+{
+ parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
+
+ XNFasprintf(&ptr->mon_identifier, "Monitor%d", screennum);
+ ptr->mon_vendor = strdup("Monitor Vendor");
+ ptr->mon_modelname = strdup("Monitor Model");
+
+ return ptr;
+}
+
+/* Initialize Configure Monitor from Detailed Timing Block */
+static void handle_detailed_input(struct detailed_monitor_section *det_mon,
+ void *data)
+{
+ XF86ConfMonitorPtr ptr = (XF86ConfMonitorPtr) data;
+
+ switch (det_mon->type) {
+ case DS_NAME:
+ ptr->mon_modelname = realloc(ptr->mon_modelname,
+ strlen((char*)(det_mon->section.name)) +
+ 1);
+ strcpy(ptr->mon_modelname,
+ (char*)(det_mon->section.name));
+ break;
+ case DS_RANGES:
+ ptr->mon_hsync[ptr->mon_n_hsync].lo =
+ det_mon->section.ranges.min_h;
+ ptr->mon_hsync[ptr->mon_n_hsync].hi =
+ det_mon->section.ranges.max_h;
+ ptr->mon_n_vrefresh = 1;
+ ptr->mon_vrefresh[ptr->mon_n_hsync].lo =
+ det_mon->section.ranges.min_v;
+ ptr->mon_vrefresh[ptr->mon_n_hsync].hi =
+ det_mon->section.ranges.max_v;
+ ptr->mon_n_hsync++;
+ default:
+ break;
+ }
+}
+
+static XF86ConfMonitorPtr
+configureDDCMonitorSection (int screennum)
+{
+ int len, mon_width, mon_height;
+#define displaySizeMaxLen 80
+ char displaySize_string[displaySizeMaxLen];
+ int displaySizeLen;
+
+ parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
+
+ XNFasprintf(&ptr->mon_identifier, "Monitor%d", screennum);
+ ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name);
+ XNFasprintf(&ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id);
+
+ /* features in centimetres, we want millimetres */
+ mon_width = 10 * ConfiguredMonitor->features.hsize ;
+ mon_height = 10 * ConfiguredMonitor->features.vsize ;
+
+#ifdef CONFIGURE_DISPLAYSIZE
+ ptr->mon_width = mon_width;
+ ptr->mon_height = mon_height;
+#else
+ if (mon_width && mon_height) {
+ /* when values available add DisplaySize option AS A COMMENT */
+
+ displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen,
+ "\t#DisplaySize\t%5d %5d\t# mm\n",
+ mon_width, mon_height);
+
+ if (displaySizeLen>0 && displaySizeLen<displaySizeMaxLen) {
+ if (ptr->mon_comment) {
+ len = strlen(ptr->mon_comment);
+ } else {
+ len = 0;
+ }
+ if ((ptr->mon_comment =
+ realloc(ptr->mon_comment, len + strlen(displaySize_string) + 1))) {
+ strcpy(ptr->mon_comment + len, displaySize_string);
+ }
+ }
+ }
+#endif /* def CONFIGURE_DISPLAYSIZE */
+
+ xf86ForEachDetailedBlock(ConfiguredMonitor, handle_detailed_input,
+ ptr);
+
+ if (ConfiguredMonitor->features.dpms) {
+ ptr->mon_option_lst = xf86addNewOption(ptr->mon_option_lst, strdup("DPMS"), NULL);
+ }
+
+ return ptr;
+}
+
+void
+DoConfigure(void)
+{
+ int i,j, screennum = -1;
+ char *home = NULL;
+ char filename[PATH_MAX];
+ char *addslash = "";
+ XF86ConfigPtr xf86config = NULL;
+ char **vlist, **vl;
+ int *dev2screen;
+
+ vlist = xf86DriverlistFromCompile();
+
+ if (!vlist) {
+ ErrorF("Missing output drivers. Configuration failed.\n");
+ goto bail;
+ }
+
+ ErrorF("List of video drivers:\n");
+ for (vl = vlist; *vl; vl++)
+ ErrorF("\t%s\n", *vl);
+
+ /* Load all the drivers that were found. */
+ xf86LoadModules(vlist, NULL);
+
+ free(vlist);
+
+ for (i = 0; i < xf86NumDrivers; i++) {
+ xorgHWFlags flags;
+ if (!xf86DriverList[i]->driverFunc
+ || !xf86DriverList[i]->driverFunc(NULL,
+ GET_REQUIRED_HW_INTERFACES,
+ &flags)
+ || NEED_IO_ENABLED(flags)) {
+ xorgHWAccess = TRUE;
+ break;
+ }
+ }
+ /* Enable full I/O access */
+ if (xorgHWAccess) {
+ if(!xf86EnableIO())
+ /* oops, we have failed */
+ xorgHWAccess = FALSE;
+ }
+
+ /* Create XF86Config file structure */
+ xf86config = calloc(1, sizeof(XF86ConfigRec));
+
+ /* Call all of the probe functions, reporting the results. */
+ for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) {
+ xorgHWFlags flags;
+ Bool found_screen;
+ DriverRec * const drv = xf86DriverList[CurrentDriver];
+
+ if (!xorgHWAccess) {
+ if (!drv->driverFunc
+ || !drv->driverFunc( NULL, GET_REQUIRED_HW_INTERFACES, &flags )
+ || NEED_IO_ENABLED(flags))
+ continue;
+ }
+
+ found_screen = xf86CallDriverProbe( drv, TRUE );
+ if ( found_screen && drv->Identify ) {
+ (*drv->Identify)(0);
+ }
+ }
+
+ if (nDevToConfig <= 0) {
+ ErrorF("No devices to configure. Configuration failed.\n");
+ goto bail;
+ }
+
+ /* Add device, monitor and screen sections for detected devices */
+ for (screennum = 0; screennum < nDevToConfig; screennum++) {
+ XF86ConfDevicePtr DevicePtr;
+ XF86ConfMonitorPtr MonitorPtr;
+ XF86ConfScreenPtr ScreenPtr;
+
+ DevicePtr = configureDeviceSection(screennum);
+ xf86config->conf_device_lst = (XF86ConfDevicePtr)xf86addListItem(
+ (glp)xf86config->conf_device_lst, (glp)DevicePtr);
+ MonitorPtr = configureMonitorSection(screennum);
+ xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
+ (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
+ ScreenPtr = configureScreenSection(screennum);
+ xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
+ (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
+ }
+
+ xf86config->conf_files = configureFilesSection();
+ xf86config->conf_modules = configureModuleSection();
+ xf86config->conf_flags = configureFlagsSection();
+ xf86config->conf_videoadaptor_lst = NULL;
+ xf86config->conf_modes_lst = NULL;
+ xf86config->conf_vendor_lst = NULL;
+ xf86config->conf_dri = NULL;
+ xf86config->conf_input_lst = configureInputSection();
+ xf86config->conf_layout_lst = configureLayoutSection();
+
+ home = getenv("HOME");
+ if ((home == NULL) || (home[0] == '\0')) {
+ home = "/";
+ } else {
+ /* Determine if trailing slash is present or needed */
+ int l = strlen(home);
+
+ if (home[l-1] != '/') {
+ addslash = "/";
+ }
+ }
+
+ snprintf(filename, sizeof(filename), "%s%s" XF86CONFIGFILE ".new",
+ home, addslash);
+
+ if (xf86writeConfigFile(filename, xf86config) == 0) {
+ xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
+ filename, strerror(errno));
+ goto bail;
+ }
+
+ xf86DoConfigurePass1 = FALSE;
+ /* Try to get DDC information filled in */
+ xf86ConfigFile = filename;
+ if (xf86HandleConfigFile(FALSE) != CONFIG_OK) {
+ goto bail;
+ }
+
+ xf86DoConfigurePass1 = FALSE;
+
+ dev2screen = xnfcalloc(1,xf86NumDrivers*sizeof(int));
+
+ {
+ Bool *driverProbed = xnfcalloc(1,xf86NumDrivers*sizeof(Bool));
+ for (screennum = 0; screennum < nDevToConfig; screennum++) {
+ int k,l,n,oldNumScreens;
+
+ i = DevToConfig[screennum].iDriver;
+
+ if (driverProbed[i]) continue;
+ driverProbed[i] = TRUE;
+
+ oldNumScreens = xf86NumScreens;
+
+ xf86CallDriverProbe( xf86DriverList[i], FALSE );
+
+ /* reorder */
+ k = screennum > 0 ? screennum : 1;
+ for (l = oldNumScreens; l < xf86NumScreens; l++) {
+ /* is screen primary? */
+ Bool primary = FALSE;
+ for (n = 0; n<xf86Screens[l]->numEntities; n++) {
+ if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) {
+ dev2screen[0] = l;
+ primary = TRUE;
+ break;
+ }
+ }
+ if (primary) continue;
+ /* not primary: assign it to next device of same driver */
+ /*
+ * NOTE: we assume that devices in DevToConfig
+ * and xf86Screens[] have the same order except
+ * for the primary device which always comes first.
+ */
+ for (; k < nDevToConfig; k++) {
+ if (DevToConfig[k].iDriver == i) {
+ dev2screen[k++] = l;
+ break;
+ }
+ }
+ }
+ }
+ free(driverProbed);
+ }
+
+
+ if (nDevToConfig != xf86NumScreens) {
+ ErrorF("Number of created screens does not match number of detected"
+ " devices.\n Configuration failed.\n");
+ goto bail;
+ }
+
+ xf86PostProbe();
+
+ for (j = 0; j < xf86NumScreens; j++) {
+ xf86Screens[j]->scrnIndex = j;
+ }
+
+ xf86freeMonitorList(xf86config->conf_monitor_lst);
+ xf86config->conf_monitor_lst = NULL;
+ xf86freeScreenList(xf86config->conf_screen_lst);
+ xf86config->conf_screen_lst = NULL;
+ for (j = 0; j < xf86NumScreens; j++) {
+ XF86ConfMonitorPtr MonitorPtr;
+ XF86ConfScreenPtr ScreenPtr;
+
+ ConfiguredMonitor = NULL;
+
+ if ((*xf86Screens[dev2screen[j]]->PreInit)(xf86Screens[dev2screen[j]],
+ PROBE_DETECT) &&
+ ConfiguredMonitor) {
+ MonitorPtr = configureDDCMonitorSection(j);
+ } else {
+ MonitorPtr = configureMonitorSection(j);
+ }
+ ScreenPtr = configureScreenSection(j);
+ xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
+ (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
+ xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
+ (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
+ }
+
+ if (xf86writeConfigFile(filename, xf86config) == 0) {
+ xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
+ filename, strerror(errno));
+ goto bail;
+ }
+
+ ErrorF("\n");
+
+ if (!foundMouse) {
+ ErrorF("\n"__XSERVERNAME__" is not able to detect your mouse.\n"
+ "Edit the file and correct the Device.\n");
+ } else {
+ ErrorF("\n"__XSERVERNAME__" detected your mouse at device %s.\n"
+ "Please check your config if the mouse is still not\n"
+ "operational, as by default "__XSERVERNAME__
+ " tries to autodetect\n"
+ "the protocol.\n",DFLT_MOUSE_DEV);
+ }
+
+ if (xf86NumScreens > 1) {
+ ErrorF("\n"__XSERVERNAME__
+ " has configured a multihead system, please check your config.\n");
+ }
+
+ ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE ,filename);
+ ErrorF("To test the server, run 'X -config %s'\n\n", filename);
+
+bail:
+ OsCleanup(TRUE);
+ AbortDDX();
+ fflush(stderr);
+ exit(0);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Events.c b/xorg-server/hw/xfree86/common/xf86Events.c
index 3006ad183..d141ce067 100644
--- a/xorg-server/hw/xfree86/common/xf86Events.c
+++ b/xorg-server/hw/xfree86/common/xf86Events.c
@@ -1,753 +1,753 @@
-/*
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- *
- * 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 Thomas Roell not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Thomas Roell makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THOMAS ROELL 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) 1994-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).
- */
-
-/* [JCH-96/01/21] Extended std reverse map to four buttons. */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xpoll.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "compiler.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#define XF86_OS_PRIVS
-#include "xf86_OSlib.h"
-#include <X11/keysym.h>
-
-#ifdef XFreeXDGA
-#include "dgaproc.h"
-#endif
-
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include "inputstr.h"
-#include "xf86Xinput.h"
-
-#include "mi.h"
-#include "mipointer.h"
-
-#include "xkbsrv.h"
-#include "xkbstr.h"
-
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
-
-/*
- * This is a toggling variable:
- * FALSE = No VT switching keys have been pressed last time around
- * TRUE = Possible VT switch Pending
- * (DWH - 12/2/93)
- *
- * This has been generalised to work with Linux and *BSD+syscons (DHD)
- */
-
-Bool VTSwitchEnabled = TRUE; /* Allows run-time disabling for
- *BSD and for avoiding VT
- switches when using the DRI
- automatic full screen mode.*/
-
-extern fd_set EnabledDevices;
-
-#ifdef XF86PM
-extern void (*xf86OSPMClose)(void);
-#endif
-
-static void xf86VTSwitch(void);
-
-/*
- * Allow arbitrary drivers or other XFree86 code to register with our main
- * Wakeup handler.
- */
-typedef struct x_IHRec {
- int fd;
- InputHandlerProc ihproc;
- pointer data;
- Bool enabled;
- struct x_IHRec * next;
-} IHRec, *IHPtr;
-
-static IHPtr InputHandlers = NULL;
-
-
-Bool
-LegalModifier(unsigned int key, DeviceIntPtr pDev)
-{
- return TRUE;
-}
-
-/*
- * TimeSinceLastInputEvent --
- * Function used for screensaver purposes by the os module. Returns the
- * time in milliseconds since there last was any input.
- */
-int
-TimeSinceLastInputEvent(void)
-{
- if (xf86Info.lastEventTime == 0) {
- xf86Info.lastEventTime = GetTimeInMillis();
- }
- return GetTimeInMillis() - xf86Info.lastEventTime;
-}
-
-/*
- * SetTimeSinceLastInputEvent --
- * Set the lastEventTime to now.
- */
-void
-SetTimeSinceLastInputEvent(void)
-{
- xf86Info.lastEventTime = GetTimeInMillis();
-}
-
-/*
- * ProcessInputEvents --
- * Retrieve all waiting input events and pass them to DIX in their
- * correct chronological order. Only reads from the system pointer
- * and keyboard.
- */
-void
-ProcessInputEvents (void)
-{
- int x, y;
-
- mieqProcessInputEvents();
-
- /* FIXME: This is a problem if we have multiple pointers */
- miPointerGetPosition(inputInfo.pointer, &x, &y);
- xf86SetViewport(xf86Info.currentScreen, x, y);
-}
-
-/*
- * Handle keyboard events that cause some kind of "action"
- * (i.e., server termination, video mode changes, VT switches, etc.)
- */
-void
-xf86ProcessActionEvent(ActionEvent action, void *arg)
-{
- DebugF("ProcessActionEvent(%d,%x)\n", (int) action, arg);
- switch (action) {
- case ACTION_TERMINATE:
- if (!xf86Info.dontZap) {
-#ifdef XFreeXDGA
- DGAShutdown();
-#endif
- GiveUp(0);
- }
- break;
- case ACTION_NEXT_MODE:
- if (!xf86Info.dontZoom)
- xf86ZoomViewport(xf86Info.currentScreen, 1);
- break;
- case ACTION_PREV_MODE:
- if (!xf86Info.dontZoom)
- xf86ZoomViewport(xf86Info.currentScreen, -1);
- break;
- case ACTION_SWITCHSCREEN:
- if (VTSwitchEnabled && !xf86Info.dontVTSwitch && arg) {
- int vtno = *((int *) arg);
-
- if (vtno != xf86Info.vtno) {
- if (!xf86VTActivate(vtno)) {
- ErrorF("Failed to switch from vt%02d to vt%02d: %s\n",
- xf86Info.vtno, vtno, strerror(errno));
- }
- }
- }
- break;
- case ACTION_SWITCHSCREEN_NEXT:
- if (VTSwitchEnabled && !xf86Info.dontVTSwitch) {
- if (!xf86VTActivate(xf86Info.vtno + 1)) {
- /* If first try failed, assume this is the last VT and
- * try wrapping around to the first vt.
- */
- if (!xf86VTActivate(1)) {
- ErrorF("Failed to switch from vt%02d to next vt: %s\n",
- xf86Info.vtno, strerror(errno));
- }
- }
- }
- break;
- case ACTION_SWITCHSCREEN_PREV:
- if (VTSwitchEnabled && !xf86Info.dontVTSwitch && xf86Info.vtno > 0) {
- if (!xf86VTActivate(xf86Info.vtno - 1)) {
- /* Don't know what the maximum VT is, so can't wrap around */
- ErrorF("Failed to switch from vt%02d to previous vt: %s\n",
- xf86Info.vtno, strerror(errno));
- }
- }
- break;
- default:
- break;
- }
-}
-
-/*
- * xf86Wakeup --
- * Os wakeup handler.
- */
-
-/* ARGSUSED */
-void
-xf86Wakeup(pointer blockData, int err, pointer pReadmask)
-{
- fd_set* LastSelectMask = (fd_set*)pReadmask;
- fd_set devicesWithInput;
- InputInfoPtr pInfo;
-
- if (err >= 0) {
-
- XFD_ANDSET(&devicesWithInput, LastSelectMask, &EnabledDevices);
- if (XFD_ANYSET(&devicesWithInput)) {
- pInfo = xf86InputDevs;
- while (pInfo) {
- if (pInfo->read_input && pInfo->fd >= 0 &&
- (FD_ISSET(pInfo->fd, &devicesWithInput) != 0)) {
- int sigstate = xf86BlockSIGIO();
-
- /*
- * Remove the descriptior from the set because more than one
- * device may share the same file descriptor.
- */
- FD_CLR(pInfo->fd, &devicesWithInput);
-
- pInfo->read_input(pInfo);
- xf86UnblockSIGIO(sigstate);
- }
- pInfo = pInfo->next;
- }
- }
- }
-
- if (err >= 0) { /* we don't want the handlers called if select() */
- IHPtr ih; /* returned with an error condition, do we? */
-
- for (ih = InputHandlers; ih; ih = ih->next) {
- if (ih->enabled && ih->fd >= 0 && ih->ihproc &&
- (FD_ISSET(ih->fd, ((fd_set *)pReadmask)) != 0)) {
- ih->ihproc(ih->fd, ih->data);
- }
- }
- }
-
- if (xf86VTSwitchPending()) xf86VTSwitch();
-}
-
-
-/*
- * xf86SigioReadInput --
- * signal handler for the SIGIO signal.
- */
-static void
-xf86SigioReadInput(int fd, void *closure)
-{
- int errno_save = errno;
- InputInfoPtr pInfo = closure;
-
- pInfo->read_input(pInfo);
-
- errno = errno_save;
-}
-
-/*
- * xf86AddEnabledDevice --
- *
- */
-void
-xf86AddEnabledDevice(InputInfoPtr pInfo)
-{
- if (!xf86InstallSIGIOHandler (pInfo->fd, xf86SigioReadInput, pInfo)) {
- AddEnabledDevice(pInfo->fd);
- }
-}
-
-/*
- * xf86RemoveEnabledDevice --
- *
- */
-void
-xf86RemoveEnabledDevice(InputInfoPtr pInfo)
-{
- if (!xf86RemoveSIGIOHandler (pInfo->fd)) {
- RemoveEnabledDevice(pInfo->fd);
- }
-}
-
-static int *xf86SignalIntercept = NULL;
-
-void
-xf86InterceptSignals(int *signo)
-{
- if ((xf86SignalIntercept = signo))
- *signo = -1;
-}
-
-static void (*xf86SigIllHandler)(void) = NULL;
-
-void
-xf86InterceptSigIll(void (*sigillhandler)(void))
-{
- xf86SigIllHandler = sigillhandler;
-}
-
-/*
- * xf86SigWrapper --
- * Catch unexpected signals and exit or continue cleanly.
- */
-int
-xf86SigWrapper(int signo)
-{
- if ((signo == SIGILL) && xf86SigIllHandler) {
- (*xf86SigIllHandler)();
- return 0; /* continue */
- }
-
- if (xf86SignalIntercept && (*xf86SignalIntercept < 0)) {
- *xf86SignalIntercept = signo;
- return 0; /* continue */
- }
-
- xf86Info.caughtSignal = TRUE;
- return 1; /* abort */
-}
-
-/*
- * xf86PrintBacktrace --
- * Print a stack backtrace for debugging purposes.
- */
-void
-xf86PrintBacktrace(void)
-{
- xorg_backtrace();
-}
-
-static void
-xf86ReleaseKeys(DeviceIntPtr pDev)
-{
- KeyClassPtr keyc;
- int i, j, nevents, sigstate;
-
- if (!pDev || !pDev->key)
- return;
-
- keyc = pDev->key;
-
- /*
- * Hmm... here is the biggest hack of every time !
- * It may be possible that a switch-vt procedure has finished BEFORE
- * you released all keys neccessary to do this. That peculiar behavior
- * can fool the X-server pretty much, cause it assumes that some keys
- * were not released. TWM may stuck alsmost completly....
- * OK, what we are doing here is after returning from the vt-switch
- * exeplicitely unrelease all keyboard keys before the input-devices
- * are reenabled.
- */
-
- for (i = keyc->xkbInfo->desc->min_key_code;
- i < keyc->xkbInfo->desc->max_key_code;
- i++) {
- if (key_is_down(pDev, i, KEY_POSTED)) {
- sigstate = xf86BlockSIGIO ();
- nevents = GetKeyboardEvents(xf86Events, pDev, KeyRelease, i, NULL);
- for (j = 0; j < nevents; j++)
- mieqEnqueue(pDev, (InternalEvent*)(xf86Events + j)->event);
- xf86UnblockSIGIO(sigstate);
- }
- }
-}
-
-/*
- * xf86VTSwitch --
- * Handle requests for switching the vt.
- */
-static void
-xf86VTSwitch(void)
-{
- int i;
- static int prevSIGIO;
- InputInfoPtr pInfo;
- IHPtr ih;
-
- DebugF("xf86VTSwitch()\n");
-
-#ifdef XFreeXDGA
- if(!DGAVTSwitch())
- return;
-#endif
-
- /*
- * Since all screens are currently all in the same state it is sufficient
- * check the first. This might change in future.
- */
- if (xf86Screens[0]->vtSema) {
-
- DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
- BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE));
-#ifdef DPMSExtension
- if (DPMSPowerLevel != DPMSModeOn)
- DPMSSet(serverClient, DPMSModeOn);
-#endif
- for (i = 0; i < xf86NumScreens; i++) {
- if (!(dispatchException & DE_TERMINATE))
- if (xf86Screens[i]->EnableDisableFBAccess)
- (*xf86Screens[i]->EnableDisableFBAccess) (i, FALSE);
- }
-
- /*
- * Keep the order: Disable Device > LeaveVT
- * EnterVT > EnableDevice
- */
- for (ih = InputHandlers; ih; ih = ih->next)
- xf86DisableInputHandler(ih);
- for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) {
- if (pInfo->dev) {
- xf86ReleaseKeys(pInfo->dev);
- ProcessInputEvents();
- DisableDevice(pInfo->dev, TRUE);
- }
- }
-
- prevSIGIO = xf86BlockSIGIO();
- for (i = 0; i < xf86NumScreens; i++)
- xf86Screens[i]->LeaveVT(i, 0);
-
- xf86AccessLeave(); /* We need this here, otherwise */
-
- if (!xf86VTSwitchAway()) {
- /*
- * switch failed
- */
-
- DebugF("xf86VTSwitch: Leave failed\n");
- xf86AccessEnter();
- for (i = 0; i < xf86NumScreens; i++) {
- if (!xf86Screens[i]->EnterVT(i, 0))
- FatalError("EnterVT failed for screen %d\n", i);
- }
- if (!(dispatchException & DE_TERMINATE)) {
- for (i = 0; i < xf86NumScreens; i++) {
- if (xf86Screens[i]->EnableDisableFBAccess)
- (*xf86Screens[i]->EnableDisableFBAccess) (i, TRUE);
- }
- }
- dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
-
- pInfo = xf86InputDevs;
- while (pInfo) {
- if (pInfo->dev)
- EnableDevice(pInfo->dev, TRUE);
- pInfo = pInfo->next;
- }
- for (ih = InputHandlers; ih; ih = ih->next)
- xf86EnableInputHandler(ih);
-
- xf86UnblockSIGIO(prevSIGIO);
-
- } else {
-#ifdef XF86PM
- if (xf86OSPMClose)
- xf86OSPMClose();
- xf86OSPMClose = NULL;
-#endif
-
- for (i = 0; i < xf86NumScreens; i++) {
- /*
- * zero all access functions to
- * trap calls when switched away.
- */
- xf86Screens[i]->vtSema = FALSE;
- }
- if (xorgHWAccess)
- xf86DisableIO();
- }
- } else {
- DebugF("xf86VTSwitch: Entering\n");
- if (!xf86VTSwitchTo()) return;
-
-#ifdef XF86PM
- xf86OSPMClose = xf86OSPMOpen();
-#endif
-
- if (xorgHWAccess)
- xf86EnableIO();
- xf86AccessEnter();
- for (i = 0; i < xf86NumScreens; i++) {
- xf86Screens[i]->vtSema = TRUE;
- if (!xf86Screens[i]->EnterVT(i, 0))
- FatalError("EnterVT failed for screen %d\n", i);
- }
- for (i = 0; i < xf86NumScreens; i++) {
- if (xf86Screens[i]->EnableDisableFBAccess)
- (*xf86Screens[i]->EnableDisableFBAccess)(i, TRUE);
- }
-
- /* Turn screen saver off when switching back */
- dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
-
- pInfo = xf86InputDevs;
- while (pInfo) {
- if (pInfo->dev)
- EnableDevice(pInfo->dev, TRUE);
- pInfo = pInfo->next;
- }
-
- for (ih = InputHandlers; ih; ih = ih->next)
- xf86EnableInputHandler(ih);
-
- xf86UnblockSIGIO(prevSIGIO);
- }
-}
-
-
-/* Input handler registration */
-
-static pointer
-addInputHandler(int fd, InputHandlerProc proc, pointer data)
-{
- IHPtr ih;
-
- if (fd < 0 || !proc)
- return NULL;
-
- ih = calloc(sizeof(*ih), 1);
- if (!ih)
- return NULL;
-
- ih->fd = fd;
- ih->ihproc = proc;
- ih->data = data;
- ih->enabled = TRUE;
-
- ih->next = InputHandlers;
- InputHandlers = ih;
-
- return ih;
-}
-
-pointer
-xf86AddInputHandler(int fd, InputHandlerProc proc, pointer data)
-{
- IHPtr ih = addInputHandler(fd, proc, data);
-
- if (ih)
- AddEnabledDevice(fd);
- return ih;
-}
-
-pointer
-xf86AddGeneralHandler(int fd, InputHandlerProc proc, pointer data)
-{
- IHPtr ih = addInputHandler(fd, proc, data);
-
- if (ih)
- AddGeneralSocket(fd);
- return ih;
-}
-
-/**
- * Set the handler for the console's fd. Replaces (and returns) the previous
- * handler or NULL, whichever appropriate.
- * proc may be NULL if the server should not handle events on the console.
- */
-InputHandlerProc
-xf86SetConsoleHandler(InputHandlerProc proc, pointer data)
-{
- static InputHandlerProc handler = NULL;
- InputHandlerProc old_handler = handler;
-
- if (old_handler)
- xf86RemoveGeneralHandler(old_handler);
-
- xf86AddGeneralHandler(xf86Info.consoleFd, proc, data);
- handler = proc;
-
- return old_handler;
-}
-
-static void
-removeInputHandler(IHPtr ih)
-{
- IHPtr p;
-
- if (ih == InputHandlers)
- InputHandlers = ih->next;
- else {
- p = InputHandlers;
- while (p && p->next != ih)
- p = p->next;
- if (ih)
- p->next = ih->next;
- }
- free(ih);
-}
-
-int
-xf86RemoveInputHandler(pointer handler)
-{
- IHPtr ih;
- int fd;
-
- if (!handler)
- return -1;
-
- ih = handler;
- fd = ih->fd;
-
- if (ih->fd >= 0)
- RemoveEnabledDevice(ih->fd);
- removeInputHandler(ih);
-
- return fd;
-}
-
-int
-xf86RemoveGeneralHandler(pointer handler)
-{
- IHPtr ih;
- int fd;
-
- if (!handler)
- return -1;
-
- ih = handler;
- fd = ih->fd;
-
- if (ih->fd >= 0)
- RemoveGeneralSocket(ih->fd);
- removeInputHandler(ih);
-
- return fd;
-}
-
-void
-xf86DisableInputHandler(pointer handler)
-{
- IHPtr ih;
-
- if (!handler)
- return;
-
- ih = handler;
- ih->enabled = FALSE;
- if (ih->fd >= 0)
- RemoveEnabledDevice(ih->fd);
-}
-
-void
-xf86DisableGeneralHandler(pointer handler)
-{
- IHPtr ih;
-
- if (!handler)
- return;
-
- ih = handler;
- ih->enabled = FALSE;
- if (ih->fd >= 0)
- RemoveGeneralSocket(ih->fd);
-}
-
-void
-xf86EnableInputHandler(pointer handler)
-{
- IHPtr ih;
-
- if (!handler)
- return;
-
- ih = handler;
- ih->enabled = TRUE;
- if (ih->fd >= 0)
- AddEnabledDevice(ih->fd);
-}
-
-void
-xf86EnableGeneralHandler(pointer handler)
-{
- IHPtr ih;
-
- if (!handler)
- return;
-
- ih = handler;
- ih->enabled = TRUE;
- if (ih->fd >= 0)
- AddGeneralSocket(ih->fd);
-}
-
-/*
- * As used currently by the DRI, the return value is ignored.
- */
-Bool
-xf86EnableVTSwitch(Bool new)
-{
- static Bool def = TRUE;
- Bool old;
-
- old = VTSwitchEnabled;
- if (!new) {
- /* Disable VT switching */
- def = VTSwitchEnabled;
- VTSwitchEnabled = FALSE;
- } else {
- /* Restore VT switching to default */
- VTSwitchEnabled = def;
- }
- return old;
-}
-
-void
-DDXRingBell(int volume, int pitch, int duration) {
- xf86OSRingBell(volume, pitch, duration);
-}
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * 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 Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL 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) 1994-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).
+ */
+
+/* [JCH-96/01/21] Extended std reverse map to four buttons. */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xpoll.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "compiler.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#define XF86_OS_PRIVS
+#include "xf86_OSlib.h"
+#include <X11/keysym.h>
+
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include "inputstr.h"
+#include "xf86Xinput.h"
+
+#include "mi.h"
+#include "mipointer.h"
+
+#include "xkbsrv.h"
+#include "xkbstr.h"
+
+#ifdef DPMSExtension
+#include <X11/extensions/dpmsconst.h>
+#include "dpmsproc.h"
+#endif
+
+/*
+ * This is a toggling variable:
+ * FALSE = No VT switching keys have been pressed last time around
+ * TRUE = Possible VT switch Pending
+ * (DWH - 12/2/93)
+ *
+ * This has been generalised to work with Linux and *BSD+syscons (DHD)
+ */
+
+Bool VTSwitchEnabled = TRUE; /* Allows run-time disabling for
+ *BSD and for avoiding VT
+ switches when using the DRI
+ automatic full screen mode.*/
+
+extern fd_set EnabledDevices;
+
+#ifdef XF86PM
+extern void (*xf86OSPMClose)(void);
+#endif
+
+static void xf86VTSwitch(void);
+
+/*
+ * Allow arbitrary drivers or other XFree86 code to register with our main
+ * Wakeup handler.
+ */
+typedef struct x_IHRec {
+ int fd;
+ InputHandlerProc ihproc;
+ pointer data;
+ Bool enabled;
+ struct x_IHRec * next;
+} IHRec, *IHPtr;
+
+static IHPtr InputHandlers = NULL;
+
+
+Bool
+LegalModifier(unsigned int key, DeviceIntPtr pDev)
+{
+ return TRUE;
+}
+
+/*
+ * TimeSinceLastInputEvent --
+ * Function used for screensaver purposes by the os module. Returns the
+ * time in milliseconds since there last was any input.
+ */
+int
+TimeSinceLastInputEvent(void)
+{
+ if (xf86Info.lastEventTime == 0) {
+ xf86Info.lastEventTime = GetTimeInMillis();
+ }
+ return GetTimeInMillis() - xf86Info.lastEventTime;
+}
+
+/*
+ * SetTimeSinceLastInputEvent --
+ * Set the lastEventTime to now.
+ */
+void
+SetTimeSinceLastInputEvent(void)
+{
+ xf86Info.lastEventTime = GetTimeInMillis();
+}
+
+/*
+ * ProcessInputEvents --
+ * Retrieve all waiting input events and pass them to DIX in their
+ * correct chronological order. Only reads from the system pointer
+ * and keyboard.
+ */
+void
+ProcessInputEvents (void)
+{
+ int x, y;
+
+ mieqProcessInputEvents();
+
+ /* FIXME: This is a problem if we have multiple pointers */
+ miPointerGetPosition(inputInfo.pointer, &x, &y);
+ xf86SetViewport(xf86Info.currentScreen, x, y);
+}
+
+/*
+ * Handle keyboard events that cause some kind of "action"
+ * (i.e., server termination, video mode changes, VT switches, etc.)
+ */
+void
+xf86ProcessActionEvent(ActionEvent action, void *arg)
+{
+ DebugF("ProcessActionEvent(%d,%x)\n", (int) action, arg);
+ switch (action) {
+ case ACTION_TERMINATE:
+ if (!xf86Info.dontZap) {
+#ifdef XFreeXDGA
+ DGAShutdown();
+#endif
+ GiveUp(0);
+ }
+ break;
+ case ACTION_NEXT_MODE:
+ if (!xf86Info.dontZoom)
+ xf86ZoomViewport(xf86Info.currentScreen, 1);
+ break;
+ case ACTION_PREV_MODE:
+ if (!xf86Info.dontZoom)
+ xf86ZoomViewport(xf86Info.currentScreen, -1);
+ break;
+ case ACTION_SWITCHSCREEN:
+ if (VTSwitchEnabled && !xf86Info.dontVTSwitch && arg) {
+ int vtno = *((int *) arg);
+
+ if (vtno != xf86Info.vtno) {
+ if (!xf86VTActivate(vtno)) {
+ ErrorF("Failed to switch from vt%02d to vt%02d: %s\n",
+ xf86Info.vtno, vtno, strerror(errno));
+ }
+ }
+ }
+ break;
+ case ACTION_SWITCHSCREEN_NEXT:
+ if (VTSwitchEnabled && !xf86Info.dontVTSwitch) {
+ if (!xf86VTActivate(xf86Info.vtno + 1)) {
+ /* If first try failed, assume this is the last VT and
+ * try wrapping around to the first vt.
+ */
+ if (!xf86VTActivate(1)) {
+ ErrorF("Failed to switch from vt%02d to next vt: %s\n",
+ xf86Info.vtno, strerror(errno));
+ }
+ }
+ }
+ break;
+ case ACTION_SWITCHSCREEN_PREV:
+ if (VTSwitchEnabled && !xf86Info.dontVTSwitch && xf86Info.vtno > 0) {
+ if (!xf86VTActivate(xf86Info.vtno - 1)) {
+ /* Don't know what the maximum VT is, so can't wrap around */
+ ErrorF("Failed to switch from vt%02d to previous vt: %s\n",
+ xf86Info.vtno, strerror(errno));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/*
+ * xf86Wakeup --
+ * Os wakeup handler.
+ */
+
+/* ARGSUSED */
+void
+xf86Wakeup(pointer blockData, int err, pointer pReadmask)
+{
+ fd_set* LastSelectMask = (fd_set*)pReadmask;
+ fd_set devicesWithInput;
+ InputInfoPtr pInfo;
+
+ if (err >= 0) {
+
+ XFD_ANDSET(&devicesWithInput, LastSelectMask, &EnabledDevices);
+ if (XFD_ANYSET(&devicesWithInput)) {
+ pInfo = xf86InputDevs;
+ while (pInfo) {
+ if (pInfo->read_input && pInfo->fd >= 0 &&
+ (FD_ISSET(pInfo->fd, &devicesWithInput) != 0)) {
+ int sigstate = xf86BlockSIGIO();
+
+ /*
+ * Remove the descriptior from the set because more than one
+ * device may share the same file descriptor.
+ */
+ FD_CLR(pInfo->fd, &devicesWithInput);
+
+ pInfo->read_input(pInfo);
+ xf86UnblockSIGIO(sigstate);
+ }
+ pInfo = pInfo->next;
+ }
+ }
+ }
+
+ if (err >= 0) { /* we don't want the handlers called if select() */
+ IHPtr ih; /* returned with an error condition, do we? */
+
+ for (ih = InputHandlers; ih; ih = ih->next) {
+ if (ih->enabled && ih->fd >= 0 && ih->ihproc &&
+ (FD_ISSET(ih->fd, ((fd_set *)pReadmask)) != 0)) {
+ ih->ihproc(ih->fd, ih->data);
+ }
+ }
+ }
+
+ if (xf86VTSwitchPending()) xf86VTSwitch();
+}
+
+
+/*
+ * xf86SigioReadInput --
+ * signal handler for the SIGIO signal.
+ */
+static void
+xf86SigioReadInput(int fd, void *closure)
+{
+ int errno_save = errno;
+ InputInfoPtr pInfo = closure;
+
+ pInfo->read_input(pInfo);
+
+ errno = errno_save;
+}
+
+/*
+ * xf86AddEnabledDevice --
+ *
+ */
+void
+xf86AddEnabledDevice(InputInfoPtr pInfo)
+{
+ if (!xf86InstallSIGIOHandler (pInfo->fd, xf86SigioReadInput, pInfo)) {
+ AddEnabledDevice(pInfo->fd);
+ }
+}
+
+/*
+ * xf86RemoveEnabledDevice --
+ *
+ */
+void
+xf86RemoveEnabledDevice(InputInfoPtr pInfo)
+{
+ if (!xf86RemoveSIGIOHandler (pInfo->fd)) {
+ RemoveEnabledDevice(pInfo->fd);
+ }
+}
+
+static int *xf86SignalIntercept = NULL;
+
+void
+xf86InterceptSignals(int *signo)
+{
+ if ((xf86SignalIntercept = signo))
+ *signo = -1;
+}
+
+static void (*xf86SigIllHandler)(void) = NULL;
+
+void
+xf86InterceptSigIll(void (*sigillhandler)(void))
+{
+ xf86SigIllHandler = sigillhandler;
+}
+
+/*
+ * xf86SigWrapper --
+ * Catch unexpected signals and exit or continue cleanly.
+ */
+int
+xf86SigWrapper(int signo)
+{
+ if ((signo == SIGILL) && xf86SigIllHandler) {
+ (*xf86SigIllHandler)();
+ return 0; /* continue */
+ }
+
+ if (xf86SignalIntercept && (*xf86SignalIntercept < 0)) {
+ *xf86SignalIntercept = signo;
+ return 0; /* continue */
+ }
+
+ xf86Info.caughtSignal = TRUE;
+ return 1; /* abort */
+}
+
+/*
+ * xf86PrintBacktrace --
+ * Print a stack backtrace for debugging purposes.
+ */
+void
+xf86PrintBacktrace(void)
+{
+ xorg_backtrace();
+}
+
+static void
+xf86ReleaseKeys(DeviceIntPtr pDev)
+{
+ KeyClassPtr keyc;
+ int i, j, nevents, sigstate;
+
+ if (!pDev || !pDev->key)
+ return;
+
+ keyc = pDev->key;
+
+ /*
+ * Hmm... here is the biggest hack of every time !
+ * It may be possible that a switch-vt procedure has finished BEFORE
+ * you released all keys neccessary to do this. That peculiar behavior
+ * can fool the X-server pretty much, cause it assumes that some keys
+ * were not released. TWM may stuck alsmost completly....
+ * OK, what we are doing here is after returning from the vt-switch
+ * exeplicitely unrelease all keyboard keys before the input-devices
+ * are reenabled.
+ */
+
+ for (i = keyc->xkbInfo->desc->min_key_code;
+ i < keyc->xkbInfo->desc->max_key_code;
+ i++) {
+ if (key_is_down(pDev, i, KEY_POSTED)) {
+ sigstate = xf86BlockSIGIO ();
+ nevents = GetKeyboardEvents(xf86Events, pDev, KeyRelease, i, NULL);
+ for (j = 0; j < nevents; j++)
+ mieqEnqueue(pDev, (InternalEvent*)(xf86Events + j)->event);
+ xf86UnblockSIGIO(sigstate);
+ }
+ }
+}
+
+/*
+ * xf86VTSwitch --
+ * Handle requests for switching the vt.
+ */
+static void
+xf86VTSwitch(void)
+{
+ int i;
+ static int prevSIGIO;
+ InputInfoPtr pInfo;
+ IHPtr ih;
+
+ DebugF("xf86VTSwitch()\n");
+
+#ifdef XFreeXDGA
+ if(!DGAVTSwitch())
+ return;
+#endif
+
+ /*
+ * Since all screens are currently all in the same state it is sufficient
+ * check the first. This might change in future.
+ */
+ if (xf86Screens[0]->vtSema) {
+
+ DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
+ BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE));
+#ifdef DPMSExtension
+ if (DPMSPowerLevel != DPMSModeOn)
+ DPMSSet(serverClient, DPMSModeOn);
+#endif
+ for (i = 0; i < xf86NumScreens; i++) {
+ if (!(dispatchException & DE_TERMINATE))
+ if (xf86Screens[i]->EnableDisableFBAccess)
+ (*xf86Screens[i]->EnableDisableFBAccess) (i, FALSE);
+ }
+
+ /*
+ * Keep the order: Disable Device > LeaveVT
+ * EnterVT > EnableDevice
+ */
+ for (ih = InputHandlers; ih; ih = ih->next)
+ xf86DisableInputHandler(ih);
+ for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) {
+ if (pInfo->dev) {
+ xf86ReleaseKeys(pInfo->dev);
+ ProcessInputEvents();
+ DisableDevice(pInfo->dev, TRUE);
+ }
+ }
+
+ prevSIGIO = xf86BlockSIGIO();
+ for (i = 0; i < xf86NumScreens; i++)
+ xf86Screens[i]->LeaveVT(i, 0);
+
+ xf86AccessLeave(); /* We need this here, otherwise */
+
+ if (!xf86VTSwitchAway()) {
+ /*
+ * switch failed
+ */
+
+ DebugF("xf86VTSwitch: Leave failed\n");
+ xf86AccessEnter();
+ for (i = 0; i < xf86NumScreens; i++) {
+ if (!xf86Screens[i]->EnterVT(i, 0))
+ FatalError("EnterVT failed for screen %d\n", i);
+ }
+ if (!(dispatchException & DE_TERMINATE)) {
+ for (i = 0; i < xf86NumScreens; i++) {
+ if (xf86Screens[i]->EnableDisableFBAccess)
+ (*xf86Screens[i]->EnableDisableFBAccess) (i, TRUE);
+ }
+ }
+ dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
+
+ pInfo = xf86InputDevs;
+ while (pInfo) {
+ if (pInfo->dev)
+ EnableDevice(pInfo->dev, TRUE);
+ pInfo = pInfo->next;
+ }
+ for (ih = InputHandlers; ih; ih = ih->next)
+ xf86EnableInputHandler(ih);
+
+ xf86UnblockSIGIO(prevSIGIO);
+
+ } else {
+#ifdef XF86PM
+ if (xf86OSPMClose)
+ xf86OSPMClose();
+ xf86OSPMClose = NULL;
+#endif
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ /*
+ * zero all access functions to
+ * trap calls when switched away.
+ */
+ xf86Screens[i]->vtSema = FALSE;
+ }
+ if (xorgHWAccess)
+ xf86DisableIO();
+ }
+ } else {
+ DebugF("xf86VTSwitch: Entering\n");
+ if (!xf86VTSwitchTo()) return;
+
+#ifdef XF86PM
+ xf86OSPMClose = xf86OSPMOpen();
+#endif
+
+ if (xorgHWAccess)
+ xf86EnableIO();
+ xf86AccessEnter();
+ for (i = 0; i < xf86NumScreens; i++) {
+ xf86Screens[i]->vtSema = TRUE;
+ if (!xf86Screens[i]->EnterVT(i, 0))
+ FatalError("EnterVT failed for screen %d\n", i);
+ }
+ for (i = 0; i < xf86NumScreens; i++) {
+ if (xf86Screens[i]->EnableDisableFBAccess)
+ (*xf86Screens[i]->EnableDisableFBAccess)(i, TRUE);
+ }
+
+ /* Turn screen saver off when switching back */
+ dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
+
+ pInfo = xf86InputDevs;
+ while (pInfo) {
+ if (pInfo->dev)
+ EnableDevice(pInfo->dev, TRUE);
+ pInfo = pInfo->next;
+ }
+
+ for (ih = InputHandlers; ih; ih = ih->next)
+ xf86EnableInputHandler(ih);
+
+ xf86UnblockSIGIO(prevSIGIO);
+ }
+}
+
+
+/* Input handler registration */
+
+static pointer
+addInputHandler(int fd, InputHandlerProc proc, pointer data)
+{
+ IHPtr ih;
+
+ if (fd < 0 || !proc)
+ return NULL;
+
+ ih = calloc(sizeof(*ih), 1);
+ if (!ih)
+ return NULL;
+
+ ih->fd = fd;
+ ih->ihproc = proc;
+ ih->data = data;
+ ih->enabled = TRUE;
+
+ ih->next = InputHandlers;
+ InputHandlers = ih;
+
+ return ih;
+}
+
+pointer
+xf86AddInputHandler(int fd, InputHandlerProc proc, pointer data)
+{
+ IHPtr ih = addInputHandler(fd, proc, data);
+
+ if (ih)
+ AddEnabledDevice(fd);
+ return ih;
+}
+
+pointer
+xf86AddGeneralHandler(int fd, InputHandlerProc proc, pointer data)
+{
+ IHPtr ih = addInputHandler(fd, proc, data);
+
+ if (ih)
+ AddGeneralSocket(fd);
+ return ih;
+}
+
+/**
+ * Set the handler for the console's fd. Replaces (and returns) the previous
+ * handler or NULL, whichever appropriate.
+ * proc may be NULL if the server should not handle events on the console.
+ */
+InputHandlerProc
+xf86SetConsoleHandler(InputHandlerProc proc, pointer data)
+{
+ static InputHandlerProc handler = NULL;
+ InputHandlerProc old_handler = handler;
+
+ if (old_handler)
+ xf86RemoveGeneralHandler(old_handler);
+
+ xf86AddGeneralHandler(xf86Info.consoleFd, proc, data);
+ handler = proc;
+
+ return old_handler;
+}
+
+static void
+removeInputHandler(IHPtr ih)
+{
+ IHPtr p;
+
+ if (ih == InputHandlers)
+ InputHandlers = ih->next;
+ else {
+ p = InputHandlers;
+ while (p && p->next != ih)
+ p = p->next;
+ if (ih)
+ p->next = ih->next;
+ }
+ free(ih);
+}
+
+int
+xf86RemoveInputHandler(pointer handler)
+{
+ IHPtr ih;
+ int fd;
+
+ if (!handler)
+ return -1;
+
+ ih = handler;
+ fd = ih->fd;
+
+ if (ih->fd >= 0)
+ RemoveEnabledDevice(ih->fd);
+ removeInputHandler(ih);
+
+ return fd;
+}
+
+int
+xf86RemoveGeneralHandler(pointer handler)
+{
+ IHPtr ih;
+ int fd;
+
+ if (!handler)
+ return -1;
+
+ ih = handler;
+ fd = ih->fd;
+
+ if (ih->fd >= 0)
+ RemoveGeneralSocket(ih->fd);
+ removeInputHandler(ih);
+
+ return fd;
+}
+
+void
+xf86DisableInputHandler(pointer handler)
+{
+ IHPtr ih;
+
+ if (!handler)
+ return;
+
+ ih = handler;
+ ih->enabled = FALSE;
+ if (ih->fd >= 0)
+ RemoveEnabledDevice(ih->fd);
+}
+
+void
+xf86DisableGeneralHandler(pointer handler)
+{
+ IHPtr ih;
+
+ if (!handler)
+ return;
+
+ ih = handler;
+ ih->enabled = FALSE;
+ if (ih->fd >= 0)
+ RemoveGeneralSocket(ih->fd);
+}
+
+void
+xf86EnableInputHandler(pointer handler)
+{
+ IHPtr ih;
+
+ if (!handler)
+ return;
+
+ ih = handler;
+ ih->enabled = TRUE;
+ if (ih->fd >= 0)
+ AddEnabledDevice(ih->fd);
+}
+
+void
+xf86EnableGeneralHandler(pointer handler)
+{
+ IHPtr ih;
+
+ if (!handler)
+ return;
+
+ ih = handler;
+ ih->enabled = TRUE;
+ if (ih->fd >= 0)
+ AddGeneralSocket(ih->fd);
+}
+
+/*
+ * As used currently by the DRI, the return value is ignored.
+ */
+Bool
+xf86EnableVTSwitch(Bool new)
+{
+ static Bool def = TRUE;
+ Bool old;
+
+ old = VTSwitchEnabled;
+ if (!new) {
+ /* Disable VT switching */
+ def = VTSwitchEnabled;
+ VTSwitchEnabled = FALSE;
+ } else {
+ /* Restore VT switching to default */
+ VTSwitchEnabled = def;
+ }
+ return old;
+}
+
+void
+DDXRingBell(int volume, int pitch, int duration) {
+ xf86OSRingBell(volume, pitch, duration);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Helper.c b/xorg-server/hw/xfree86/common/xf86Helper.c
index 3cdffdb43..da15b0503 100644
--- a/xorg-server/hw/xfree86/common/xf86Helper.c
+++ b/xorg-server/hw/xfree86/common/xf86Helper.c
@@ -1,1949 +1,1949 @@
-/*
- * Copyright (c) 1997-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).
- */
-
-/*
- * Authors: Dirk Hohndel <hohndel@XFree86.Org>
- * David Dawes <dawes@XFree86.Org>
- * ... and others
- *
- * This file includes the helper functions that the server provides for
- * different drivers.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "os.h"
-#include "servermd.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "propertyst.h"
-#include "gcstruct.h"
-#include "loaderProcs.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#include "micmap.h"
-#include "xf86DDC.h"
-#include "xf86Xinput.h"
-#include "xf86InPriv.h"
-#include "mivalidate.h"
-#include "xf86Crtc.h"
-
-/* For xf86GetClocks */
-#if defined(CSRG_BASED) || defined(__GNU__)
-#define HAS_SETPRIORITY
-#include <sys/resource.h>
-#endif
-
-static int xf86ScrnInfoPrivateCount = 0;
-
-
-/* Add a pointer to a new DriverRec to xf86DriverList */
-
-void
-xf86AddDriver(DriverPtr driver, pointer module, int flags)
-{
- /* Don't add null entries */
- if (!driver)
- return;
-
- if (xf86DriverList == NULL)
- xf86NumDrivers = 0;
-
- xf86NumDrivers++;
- xf86DriverList = xnfrealloc(xf86DriverList,
- xf86NumDrivers * sizeof(DriverPtr));
- xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec));
- if (flags & HaveDriverFuncs)
- *xf86DriverList[xf86NumDrivers - 1] = *driver;
- else {
- (void) memset( xf86DriverList[xf86NumDrivers - 1], 0,
- sizeof( DriverRec ) );
- (void) memcpy( xf86DriverList[xf86NumDrivers - 1], driver,
- sizeof(DriverRec1));
-
- }
- xf86DriverList[xf86NumDrivers - 1]->module = module;
- xf86DriverList[xf86NumDrivers - 1]->refCount = 0;
-}
-
-void
-xf86DeleteDriver(int drvIndex)
-{
- if (xf86DriverList[drvIndex]
- && (!xf86DriverHasEntities(xf86DriverList[drvIndex]))) {
- if (xf86DriverList[drvIndex]->module)
- UnloadModule(xf86DriverList[drvIndex]->module);
- free(xf86DriverList[drvIndex]);
- xf86DriverList[drvIndex] = NULL;
- }
-}
-
-/* Add a pointer to a new InputDriverRec to xf86InputDriverList */
-
-void
-xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags)
-{
- /* Don't add null entries */
- if (!driver)
- return;
-
- if (xf86InputDriverList == NULL)
- xf86NumInputDrivers = 0;
-
- xf86NumInputDrivers++;
- xf86InputDriverList = xnfrealloc(xf86InputDriverList,
- xf86NumInputDrivers * sizeof(InputDriverPtr));
- xf86InputDriverList[xf86NumInputDrivers - 1] =
- xnfalloc(sizeof(InputDriverRec));
- *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver;
- xf86InputDriverList[xf86NumInputDrivers - 1]->module = module;
-}
-
-void
-xf86DeleteInputDriver(int drvIndex)
-{
- if (xf86InputDriverList[drvIndex] && xf86InputDriverList[drvIndex]->module)
- UnloadModule(xf86InputDriverList[drvIndex]->module);
- free(xf86InputDriverList[drvIndex]);
- xf86InputDriverList[drvIndex] = NULL;
-}
-
-InputDriverPtr
-xf86LookupInputDriver(const char *name)
-{
- int i;
-
- for (i = 0; i < xf86NumInputDrivers; i++) {
- if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName &&
- xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0)
- return xf86InputDriverList[i];
- }
- return NULL;
-}
-
-InputInfoPtr
-xf86LookupInput(const char *name)
-{
- InputInfoPtr p;
-
- for (p = xf86InputDevs; p != NULL; p = p->next) {
- if (strcmp(name, p->name) == 0)
- return p;
- }
-
- return NULL;
-}
-
-/* Allocate a new ScrnInfoRec in xf86Screens */
-
-ScrnInfoPtr
-xf86AllocateScreen(DriverPtr drv, int flags)
-{
- int i;
-
- if (xf86Screens == NULL)
- xf86NumScreens = 0;
-
- i = xf86NumScreens++;
- xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
- xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
- xf86Screens[i]->scrnIndex = i; /* Changes when a screen is removed */
- xf86Screens[i]->origIndex = i; /* This never changes */
- xf86Screens[i]->privates = xnfcalloc(sizeof(DevUnion),
- xf86ScrnInfoPrivateCount);
- /*
- * EnableDisableFBAccess now gets initialized in InitOutput()
- * xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
- */
-
- xf86Screens[i]->drv = drv;
- drv->refCount++;
- xf86Screens[i]->module = DuplicateModule(drv->module, NULL);
-
- xf86Screens[i]->DriverFunc = drv->driverFunc;
-
- return xf86Screens[i];
-}
-
-
-/*
- * Remove an entry from xf86Screens. Ideally it should free all allocated
- * data. To do this properly may require a driver hook.
- */
-
-void
-xf86DeleteScreen(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn;
- int i;
-
- /* First check if the screen is valid */
- if (xf86NumScreens == 0 || xf86Screens == NULL)
- return;
-
- if (scrnIndex > xf86NumScreens - 1)
- return;
-
- if (!(pScrn = xf86Screens[scrnIndex]))
- return;
-
- /* If a FreeScreen function is defined, call it here */
- if (pScrn->FreeScreen != NULL)
- pScrn->FreeScreen(scrnIndex, 0);
-
- while (pScrn->modes)
- xf86DeleteMode(&pScrn->modes, pScrn->modes);
-
- while (pScrn->modePool)
- xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
-
- xf86OptionListFree(pScrn->options);
-
- if (pScrn->module)
- UnloadModule(pScrn->module);
-
- if (pScrn->drv)
- pScrn->drv->refCount--;
-
- free(pScrn->privates);
-
- xf86ClearEntityListForScreen(scrnIndex);
-
- free(pScrn);
-
- /* Move the other entries down, updating their scrnIndex fields */
-
- xf86NumScreens--;
-
- for (i = scrnIndex; i < xf86NumScreens; i++) {
- xf86Screens[i] = xf86Screens[i + 1];
- xf86Screens[i]->scrnIndex = i;
- /* Also need to take care of the screen layout settings */
- }
-}
-
-/*
- * Allocate a private in ScrnInfoRec.
- */
-
-int
-xf86AllocateScrnInfoPrivateIndex(void)
-{
- int idx, i;
- ScrnInfoPtr pScr;
- DevUnion *nprivs;
-
- idx = xf86ScrnInfoPrivateCount++;
- for (i = 0; i < xf86NumScreens; i++) {
- pScr = xf86Screens[i];
- nprivs = xnfrealloc(pScr->privates,
- xf86ScrnInfoPrivateCount * sizeof(DevUnion));
- /* Zero the new private */
- memset(&nprivs[idx], 0, sizeof(DevUnion));
- pScr->privates = nprivs;
- }
- return idx;
-}
-
-Bool
-xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad)
-{
- int i;
-
- if (pScrn->numFormats >= MAXFORMATS)
- return FALSE;
-
- if (bpp <= 0) {
- if (depth == 1)
- bpp = 1;
- else if (depth <= 8)
- bpp = 8;
- else if (depth <= 16)
- bpp = 16;
- else if (depth <= 32)
- bpp = 32;
- else
- return FALSE;
- }
- if (pad <= 0)
- pad = BITMAP_SCANLINE_PAD;
-
- i = pScrn->numFormats++;
- pScrn->formats[i].depth = depth;
- pScrn->formats[i].bitsPerPixel = bpp;
- pScrn->formats[i].scanlinePad = pad;
- return TRUE;
-}
-
-/*
- * Set the depth we are using based on (in the following order of preference):
- * - values given on the command line
- * - values given in the config file
- * - values provided by the driver
- * - an overall default when nothing else is given
- *
- * Also find a Display subsection matching the depth/bpp found.
- *
- * Sets the following ScrnInfoRec fields:
- * bitsPerPixel, pixmap24, depth, display, imageByteOrder,
- * bitmapScanlinePad, bitmapScanlineUnit, bitmapBitOrder, numFormats,
- * formats, fbFormat.
- */
-
-/* Can the screen handle 24 bpp pixmaps */
-#define DO_PIX24(f) ((f & Support24bppFb) || \
- ((f & Support32bppFb) && (f & SupportConvert24to32)))
-
-/* Can the screen handle 32 bpp pixmaps */
-#define DO_PIX32(f) ((f & Support32bppFb) || \
- ((f & Support24bppFb) && (f & SupportConvert32to24)))
-
-/* Does the screen prefer 32bpp fb for 24bpp pixmaps */
-#define CHOOSE32FOR24(f) ((f & Support32bppFb) && (f & SupportConvert24to32) \
- && (f & PreferConvert24to32))
-
-/* Does the screen prefer 24bpp fb for 32bpp pixmaps */
-#define CHOOSE24FOR32(f) ((f & Support24bppFb) && (f & SupportConvert32to24) \
- && (f & PreferConvert32to24))
-
-/* Can the screen handle 32bpp pixmaps for 24bpp fb */
-#define DO_PIX32FOR24(f) ((f & Support24bppFb) && (f & SupportConvert32to24))
-
-/* Can the screen handle 24bpp pixmaps for 32bpp fb */
-#define DO_PIX24FOR32(f) ((f & Support32bppFb) && (f & SupportConvert24to32))
-
-#ifndef GLOBAL_DEFAULT_DEPTH
-#define GLOBAL_DEFAULT_DEPTH 24
-#endif
-
-Bool
-xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
- int depth24flags)
-{
- int i;
- DispPtr disp;
- Pix24Flags pix24 = xf86Info.pixmap24;
- Bool nomatch = FALSE;
-
- scrp->bitsPerPixel = -1;
- scrp->depth = -1;
- scrp->pixmap24 = Pix24DontCare;
- scrp->bitsPerPixelFrom = X_DEFAULT;
- scrp->depthFrom = X_DEFAULT;
-
- if (xf86FbBpp > 0) {
- scrp->bitsPerPixel = xf86FbBpp;
- scrp->bitsPerPixelFrom = X_CMDLINE;
- }
-
- if (xf86Depth > 0) {
- scrp->depth = xf86Depth;
- scrp->depthFrom = X_CMDLINE;
- }
-
- if (xf86FbBpp < 0 && xf86Depth < 0) {
- if (scrp->confScreen->defaultfbbpp > 0) {
- scrp->bitsPerPixel = scrp->confScreen->defaultfbbpp;
- scrp->bitsPerPixelFrom = X_CONFIG;
- }
- if (scrp->confScreen->defaultdepth > 0) {
- scrp->depth = scrp->confScreen->defaultdepth;
- scrp->depthFrom = X_CONFIG;
- }
-
- if (scrp->confScreen->defaultfbbpp <= 0 &&
- scrp->confScreen->defaultdepth <= 0) {
- /*
- * Check for DefaultDepth and DefaultFbBpp options in the
- * Device sections.
- */
- int i;
- GDevPtr device;
- Bool found = FALSE;
-
- for (i = 0; i < scrp->numEntities; i++) {
- device = xf86GetDevFromEntity(scrp->entityList[i],
- scrp->entityInstanceList[i]);
- if (device && device->options) {
- if (xf86FindOption(device->options, "DefaultDepth")) {
- scrp->depth = xf86SetIntOption(device->options,
- "DefaultDepth", -1);
- scrp->depthFrom = X_CONFIG;
- found = TRUE;
- }
- if (xf86FindOption(device->options, "DefaultFbBpp")) {
- scrp->bitsPerPixel = xf86SetIntOption(device->options,
- "DefaultFbBpp",
- -1);
- scrp->bitsPerPixelFrom = X_CONFIG;
- found = TRUE;
- }
- }
- if (found)
- break;
- }
- }
- }
-
- /* If none of these is set, pick a default */
- if (scrp->bitsPerPixel < 0 && scrp->depth < 0) {
- if (fbbpp > 0 || depth > 0) {
- if (fbbpp > 0)
- scrp->bitsPerPixel = fbbpp;
- if (depth > 0)
- scrp->depth = depth;
- } else {
- scrp->depth = GLOBAL_DEFAULT_DEPTH;
- }
- }
-
- /* If any are not given, determine a default for the others */
-
- if (scrp->bitsPerPixel < 0) {
- /* The depth must be set */
- if (scrp->depth > -1) {
- if (scrp->depth == 1)
- scrp->bitsPerPixel = 1;
- else if (scrp->depth <= 4)
- scrp->bitsPerPixel = 4;
- else if (scrp->depth <= 8)
- scrp->bitsPerPixel = 8;
- else if (scrp->depth <= 16)
- scrp->bitsPerPixel = 16;
- else if (scrp->depth <= 24) {
- /*
- * Figure out if a choice is possible based on the depth24
- * and pix24 flags.
- */
- /* Check pix24 first */
- if (pix24 != Pix24DontCare) {
- if (pix24 == Pix24Use32) {
- if (DO_PIX32(depth24flags)) {
- if (CHOOSE24FOR32(depth24flags))
- scrp->bitsPerPixel = 24;
- else
- scrp->bitsPerPixel = 32;
- } else {
- nomatch = TRUE;
- }
- } else if (pix24 == Pix24Use24) {
- if (DO_PIX24(depth24flags)) {
- if (CHOOSE32FOR24(depth24flags))
- scrp->bitsPerPixel = 32;
- else
- scrp->bitsPerPixel = 24;
- } else {
- nomatch = TRUE;
- }
- }
- } else {
- if (DO_PIX32(depth24flags)) {
- if (CHOOSE24FOR32(depth24flags))
- scrp->bitsPerPixel = 24;
- else
- scrp->bitsPerPixel = 32;
- } else if (DO_PIX24(depth24flags)) {
- if (CHOOSE32FOR24(depth24flags))
- scrp->bitsPerPixel = 32;
- else
- scrp->bitsPerPixel = 24;
- }
- }
- } else if (scrp->depth <= 32)
- scrp->bitsPerPixel = 32;
- else {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Specified depth (%d) is greater than 32\n",
- scrp->depth);
- return FALSE;
- }
- } else {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "xf86SetDepthBpp: internal error: depth and fbbpp"
- " are both not set\n");
- return FALSE;
- }
- if (scrp->bitsPerPixel < 0) {
- if (nomatch)
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Driver can't support depth 24 pixmap format (%d)\n",
- PIX24TOBPP(pix24));
- else if ((depth24flags & (Support24bppFb | Support32bppFb)) ==
- NoDepth24Support)
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Driver can't support depth 24\n");
- else
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Can't find fbbpp for depth 24\n");
- return FALSE;
- }
- scrp->bitsPerPixelFrom = X_PROBED;
- }
-
- if (scrp->depth <= 0) {
- /* bitsPerPixel is already set */
- switch (scrp->bitsPerPixel) {
- case 32:
- scrp->depth = 24;
- break;
- default:
- /* 1, 4, 8, 16 and 24 */
- scrp->depth = scrp->bitsPerPixel;
- break;
- }
- scrp->depthFrom = X_PROBED;
- }
-
- /* Sanity checks */
- if (scrp->depth < 1 || scrp->depth > 32) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Specified depth (%d) is not in the range 1-32\n",
- scrp->depth);
- return FALSE;
- }
- switch (scrp->bitsPerPixel) {
- case 1:
- case 4:
- case 8:
- case 16:
- case 24:
- case 32:
- break;
- default:
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Specified fbbpp (%d) is not a permitted value\n",
- scrp->bitsPerPixel);
- return FALSE;
- }
- if (scrp->depth > scrp->bitsPerPixel) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Specified depth (%d) is greater than the fbbpp (%d)\n",
- scrp->depth, scrp->bitsPerPixel);
- return FALSE;
- }
-
- /* set scrp->pixmap24 if the driver isn't flexible */
- if (scrp->bitsPerPixel == 24 && !DO_PIX32FOR24(depth24flags)) {
- scrp->pixmap24 = Pix24Use24;
- }
- if (scrp->bitsPerPixel == 32 && !DO_PIX24FOR32(depth24flags)) {
- scrp->pixmap24 = Pix24Use32;
- }
-
- /*
- * Find the Display subsection matching the depth/fbbpp and initialise
- * scrp->display with it.
- */
- for (i = 0, disp = scrp->confScreen->displays;
- i < scrp->confScreen->numdisplays; i++, disp++) {
- if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel)
- || (disp->depth == scrp->depth && disp->fbbpp <= 0)
- || (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) {
- scrp->display = disp;
- break;
- }
- }
-
- /*
- * If an exact match can't be found, see if there is one with no
- * depth or fbbpp specified.
- */
- if (i == scrp->confScreen->numdisplays) {
- for (i = 0, disp = scrp->confScreen->displays;
- i < scrp->confScreen->numdisplays; i++, disp++) {
- if (disp->depth <= 0 && disp->fbbpp <= 0) {
- scrp->display = disp;
- break;
- }
- }
- }
-
- /*
- * If all else fails, create a default one.
- */
- if (i == scrp->confScreen->numdisplays) {
- scrp->confScreen->numdisplays++;
- scrp->confScreen->displays =
- xnfrealloc(scrp->confScreen->displays,
- scrp->confScreen->numdisplays * sizeof(DispRec));
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Creating default Display subsection in Screen section\n"
- "\t\"%s\" for depth/fbbpp %d/%d\n",
- scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel);
- memset(&scrp->confScreen->displays[i], 0, sizeof(DispRec));
- scrp->confScreen->displays[i].blackColour.red = -1;
- scrp->confScreen->displays[i].blackColour.green = -1;
- scrp->confScreen->displays[i].blackColour.blue = -1;
- scrp->confScreen->displays[i].whiteColour.red = -1;
- scrp->confScreen->displays[i].whiteColour.green = -1;
- scrp->confScreen->displays[i].whiteColour.blue = -1;
- scrp->confScreen->displays[i].defaultVisual = -1;
- scrp->confScreen->displays[i].modes = xnfalloc(sizeof(char *));
- scrp->confScreen->displays[i].modes[0] = NULL;
- scrp->confScreen->displays[i].depth = depth;
- scrp->confScreen->displays[i].fbbpp = fbbpp;
- scrp->display = &scrp->confScreen->displays[i];
- }
-
- /*
- * Setup defaults for the display-wide attributes the framebuffer will
- * need. These defaults should eventually be set globally, and not
- * dependent on the screens.
- */
- scrp->imageByteOrder = IMAGE_BYTE_ORDER;
- scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
- if (scrp->depth < 8) {
- /* Planar modes need these settings */
- scrp->bitmapScanlineUnit = 8;
- scrp->bitmapBitOrder = MSBFirst;
- } else {
- scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
- scrp->bitmapBitOrder = BITMAP_BIT_ORDER;
- }
-
- /*
- * If an unusual depth is required, add it to scrp->formats. The formats
- * for the common depths are handled globally in InitOutput
- */
- switch (scrp->depth) {
- case 1:
- case 4:
- case 8:
- case 15:
- case 16:
- case 24:
- /* Common depths. Nothing to do for them */
- break;
- default:
- if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Can't add pixmap format for depth %d\n", scrp->depth);
- return FALSE;
- }
- }
-
- /* Initialise the framebuffer format for this screen */
- scrp->fbFormat.depth = scrp->depth;
- scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel;
- scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD;
-
- return TRUE;
-}
-
-/*
- * Print out the selected depth and bpp.
- */
-void
-xf86PrintDepthBpp(ScrnInfoPtr scrp)
-{
- xf86DrvMsg(scrp->scrnIndex, scrp->depthFrom, "Depth %d, ", scrp->depth);
- xf86Msg(scrp->bitsPerPixelFrom, "framebuffer bpp %d\n", scrp->bitsPerPixel);
-}
-
-/*
- * xf86SetWeight sets scrp->weight, scrp->mask, scrp->offset, and for depths
- * greater than MAX_PSEUDO_DEPTH also scrp->rgbBits.
- */
-Bool
-xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)
-{
- MessageType weightFrom = X_DEFAULT;
-
- scrp->weight.red = 0;
- scrp->weight.green = 0;
- scrp->weight.blue = 0;
-
- if (xf86Weight.red > 0 && xf86Weight.green > 0 && xf86Weight.blue > 0) {
- scrp->weight = xf86Weight;
- weightFrom = X_CMDLINE;
- } else if (scrp->display->weight.red > 0 && scrp->display->weight.green > 0
- && scrp->display->weight.blue > 0) {
- scrp->weight = scrp->display->weight;
- weightFrom = X_CONFIG;
- } else if (weight.red > 0 && weight.green > 0 && weight.blue > 0) {
- scrp->weight = weight;
- } else {
- switch (scrp->depth) {
- case 1:
- case 4:
- case 8:
- scrp->weight.red = scrp->weight.green =
- scrp->weight.blue = scrp->rgbBits;
- break;
- case 15:
- scrp->weight.red = scrp->weight.green = scrp->weight.blue = 5;
- break;
- case 16:
- scrp->weight.red = scrp->weight.blue = 5;
- scrp->weight.green = 6;
- break;
- case 18:
- scrp->weight.red = scrp->weight.green = scrp->weight.blue = 6;
- break;
- case 24:
- scrp->weight.red = scrp->weight.green = scrp->weight.blue = 8;
- break;
- case 30:
- scrp->weight.red = scrp->weight.green = scrp->weight.blue = 10;
- break;
- }
- }
-
- if (scrp->weight.red)
- xf86DrvMsg(scrp->scrnIndex, weightFrom, "RGB weight %d%d%d\n",
- (int)scrp->weight.red, (int)scrp->weight.green,
- (int)scrp->weight.blue);
-
- if (scrp->depth > MAX_PSEUDO_DEPTH &&
- (scrp->depth != scrp->weight.red + scrp->weight.green +
- scrp->weight.blue)) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Weight given (%d%d%d) is inconsistent with the "
- "depth (%d)\n",
- (int)scrp->weight.red, (int)scrp->weight.green,
- (int)scrp->weight.blue, scrp->depth);
- return FALSE;
- }
- if (scrp->depth > MAX_PSEUDO_DEPTH && scrp->weight.red) {
- /*
- * XXX Does this even mean anything for TrueColor visuals?
- * If not, we shouldn't even be setting it here. However, this
- * matches the behaviour of 3.x versions of XFree86.
- */
- scrp->rgbBits = scrp->weight.red;
- if (scrp->weight.green > scrp->rgbBits)
- scrp->rgbBits = scrp->weight.green;
- if (scrp->weight.blue > scrp->rgbBits)
- scrp->rgbBits = scrp->weight.blue;
- }
-
- /* Set the mask and offsets */
- if (mask.red == 0 || mask.green == 0 || mask.blue == 0) {
- /* Default to a setting common to PC hardware */
- scrp->offset.red = scrp->weight.green + scrp->weight.blue;
- scrp->offset.green = scrp->weight.blue;
- scrp->offset.blue = 0;
- scrp->mask.red = ((1 << scrp->weight.red) - 1) << scrp->offset.red;
- scrp->mask.green = ((1 << scrp->weight.green) - 1)
- << scrp->offset.green;
- scrp->mask.blue = (1 << scrp->weight.blue) - 1;
- } else {
- /* Initialise to the values passed */
- scrp->mask.red = mask.red;
- scrp->mask.green = mask.green;
- scrp->mask.blue = mask.blue;
- scrp->offset.red = ffs(mask.red);
- scrp->offset.green = ffs(mask.green);
- scrp->offset.blue = ffs(mask.blue);
- }
- return TRUE;
-}
-
-Bool
-xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)
-{
- MessageType visualFrom = X_DEFAULT;
-
- if (defaultColorVisualClass >= 0) {
- scrp->defaultVisual = defaultColorVisualClass;
- visualFrom = X_CMDLINE;
- } else if (scrp->display->defaultVisual >= 0) {
- scrp->defaultVisual = scrp->display->defaultVisual;
- visualFrom = X_CONFIG;
- } else if (visual >= 0) {
- scrp->defaultVisual = visual;
- } else {
- if (scrp->depth == 1)
- scrp->defaultVisual = StaticGray;
- else if (scrp->depth == 4)
- scrp->defaultVisual = StaticColor;
- else if (scrp->depth <= MAX_PSEUDO_DEPTH)
- scrp->defaultVisual = PseudoColor;
- else
- scrp->defaultVisual = TrueColor;
- }
- switch (scrp->defaultVisual) {
- case StaticGray:
- case GrayScale:
- case StaticColor:
- case PseudoColor:
- case TrueColor:
- case DirectColor:
- xf86DrvMsg(scrp->scrnIndex, visualFrom, "Default visual is %s\n",
- xf86VisualNames[scrp->defaultVisual]);
- return TRUE;
- default:
-
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Invalid default visual class (%d)\n", scrp->defaultVisual);
- return FALSE;
- }
-}
-
-#define TEST_GAMMA(g) \
- (g).red > GAMMA_ZERO || (g).green > GAMMA_ZERO || (g).blue > GAMMA_ZERO
-
-#define SET_GAMMA(g) \
- (g) > GAMMA_ZERO ? (g) : 1.0
-
-Bool
-xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)
-{
- MessageType from = X_DEFAULT;
-#if 0
- xf86MonPtr DDC = (xf86MonPtr)(scrp->monitor->DDC);
-#endif
- if (TEST_GAMMA(xf86Gamma)) {
- from = X_CMDLINE;
- scrp->gamma.red = SET_GAMMA(xf86Gamma.red);
- scrp->gamma.green = SET_GAMMA(xf86Gamma.green);
- scrp->gamma.blue = SET_GAMMA(xf86Gamma.blue);
- } else if (TEST_GAMMA(scrp->monitor->gamma)) {
- from = X_CONFIG;
- scrp->gamma.red = SET_GAMMA(scrp->monitor->gamma.red);
- scrp->gamma.green = SET_GAMMA(scrp->monitor->gamma.green);
- scrp->gamma.blue = SET_GAMMA(scrp->monitor->gamma.blue);
-#if 0
- } else if ( DDC && DDC->features.gamma > GAMMA_ZERO ) {
- from = X_PROBED;
- scrp->gamma.red = SET_GAMMA(DDC->features.gamma);
- scrp->gamma.green = SET_GAMMA(DDC->features.gamma);
- scrp->gamma.blue = SET_GAMMA(DDC->features.gamma);
- /* EDID structure version 2 gives optional seperate red, green & blue gamma values
- * in bytes 0x57-0x59 */
-#endif
- } else if (TEST_GAMMA(gamma)) {
- scrp->gamma.red = SET_GAMMA(gamma.red);
- scrp->gamma.green = SET_GAMMA(gamma.green);
- scrp->gamma.blue = SET_GAMMA(gamma.blue);
- } else {
- scrp->gamma.red = 1.0;
- scrp->gamma.green = 1.0;
- scrp->gamma.blue = 1.0;
- }
- /* Pretend we succeeded if we support better a gamma system.
- * This avoids a confusing message.
- */
- if (xf86_crtc_supports_gamma(scrp))
- return TRUE;
- xf86DrvMsg(scrp->scrnIndex, from,
- "Using gamma correction (%.1f, %.1f, %.1f)\n",
- scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue);
-
- return TRUE;
-}
-
-#undef TEST_GAMMA
-#undef SET_GAMMA
-
-
-/*
- * Set the DPI from the command line option. XXX should allow it to be
- * calculated from the widthmm/heightmm values.
- */
-
-#undef MMPERINCH
-#define MMPERINCH 25.4
-
-void
-xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
-{
- MessageType from = X_DEFAULT;
- xf86MonPtr DDC = (xf86MonPtr)(pScrn->monitor->DDC);
- int ddcWidthmm, ddcHeightmm;
- int widthErr, heightErr;
-
- /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
- pScrn->widthmm = pScrn->monitor->widthmm;
- pScrn->heightmm = pScrn->monitor->heightmm;
-
- if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0) ) {
- /* DDC gives display size in mm for individual modes,
- * but cm for monitor
- */
- ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
- ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
- } else {
- ddcWidthmm = ddcHeightmm = 0;
- }
-
- if (monitorResolution > 0) {
- pScrn->xDpi = monitorResolution;
- pScrn->yDpi = monitorResolution;
- from = X_CMDLINE;
- } else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) {
- from = X_CONFIG;
- if (pScrn->widthmm > 0) {
- pScrn->xDpi =
- (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
- }
- if (pScrn->heightmm > 0) {
- pScrn->yDpi =
- (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
- }
- if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
- pScrn->yDpi = pScrn->xDpi;
- if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
- pScrn->xDpi = pScrn->yDpi;
- xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
- pScrn->widthmm, pScrn->heightmm);
-
- /* Warn if config and probe disagree about display size */
- if ( ddcWidthmm && ddcHeightmm ) {
- if (pScrn->widthmm > 0) {
- widthErr = abs(ddcWidthmm - pScrn->widthmm);
- } else {
- widthErr = 0;
- }
- if (pScrn->heightmm > 0) {
- heightErr = abs(ddcHeightmm - pScrn->heightmm);
- } else {
- heightErr = 0;
- }
- if (widthErr>10 || heightErr>10) {
- /* Should include config file name for monitor here */
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
- ddcWidthmm,ddcHeightmm, pScrn->widthmm,pScrn->heightmm);
- }
- }
- } else if ( ddcWidthmm && ddcHeightmm ) {
- from = X_PROBED;
- xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
- ddcWidthmm, ddcHeightmm );
- pScrn->widthmm = ddcWidthmm;
- pScrn->heightmm = ddcHeightmm;
- if (pScrn->widthmm > 0) {
- pScrn->xDpi =
- (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
- }
- if (pScrn->heightmm > 0) {
- pScrn->yDpi =
- (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
- }
- if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
- pScrn->yDpi = pScrn->xDpi;
- if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
- pScrn->xDpi = pScrn->yDpi;
- } else {
- if (x > 0)
- pScrn->xDpi = x;
- else
- pScrn->xDpi = DEFAULT_DPI;
- if (y > 0)
- pScrn->yDpi = y;
- else
- pScrn->yDpi = DEFAULT_DPI;
- }
- xf86DrvMsg(pScrn->scrnIndex, from, "DPI set to (%d, %d)\n",
- pScrn->xDpi, pScrn->yDpi);
-}
-
-#undef MMPERINCH
-
-
-void
-xf86SetBlackWhitePixels(ScreenPtr pScreen)
-{
- if (xf86FlipPixels) {
- pScreen->whitePixel = 0;
- pScreen->blackPixel = 1;
- } else {
- pScreen->whitePixel = 1;
- pScreen->blackPixel = 0;
- }
-}
-
-/*
- * Function to enable/disable access to the frame buffer
- *
- * This is used when VT switching and when entering/leaving DGA direct mode.
- *
- * This has been rewritten again to eliminate the saved pixmap. The
- * devPrivate field in the screen pixmap is set to NULL to catch code
- * accidentally referencing the frame buffer while the X server is not
- * supposed to touch it.
- *
- * Here, we exchange the pixmap private data, rather than the pixmaps
- * themselves to avoid having to find and change any references to the screen
- * pixmap such as GC's, window privates etc. This also means that this code
- * does not need to know exactly how the pixmap pixels are accessed. Further,
- * this exchange is >not< done through the screen's ModifyPixmapHeader()
- * vector. This means the called frame buffer code layers can determine
- * whether they are switched in or out by keeping track of the root pixmap's
- * private data, and therefore don't need to access pScrnInfo->vtSema.
- */
-void
-xf86EnableDisableFBAccess(int scrnIndex, Bool enable)
-{
- ScrnInfoPtr pScrnInfo = xf86Screens[scrnIndex];
- ScreenPtr pScreen = pScrnInfo->pScreen;
- PixmapPtr pspix;
-
- pspix = (*pScreen->GetScreenPixmap) (pScreen);
- if (enable)
- {
- /*
- * Restore all of the clip lists on the screen
- */
- if (!xf86Resetting)
- SetRootClip (pScreen, TRUE);
-
- }
- else
- {
- /*
- * Empty all of the clip lists on the screen
- */
- SetRootClip (pScreen, FALSE);
- }
-}
-
-/* Print driver messages in the standard format */
-
-#undef PREFIX_SIZE
-#define PREFIX_SIZE 14
-
-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
- LogVMessageVerb(type, verb, format, args);
-}
-#undef PREFIX_SIZE
-
-/* Print driver messages, with verbose level specified directly */
-void
-xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
- ...)
-{
- va_list ap;
-
- va_start(ap, format);
- xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap);
- va_end(ap);
-}
-
-/* Print driver messages, with verbose level of 1 (default) */
-void
-xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap);
- va_end(ap);
-}
-
-/* Print input driver messages in the standard format of
- <driver>: <device name>: <message> */
-void
-xf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format,
- va_list args)
-{
- char *msg;
-
- 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);
- }
-}
-
-/* Print input driver message, with verbose level specified directly */
-void
-xf86IDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format,
- ...)
-{
- va_list ap;
-
- va_start(ap, format);
- xf86VIDrvMsgVerb(dev, type, verb, format, ap);
- va_end(ap);
-}
-
-/* Print input driver messages, with verbose level of 1 (default) */
-void
-xf86IDrvMsg(InputInfoPtr dev, MessageType type, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- xf86VIDrvMsgVerb(dev, type, 1, format, ap);
- va_end(ap);
-}
-
-
-/* Print non-driver messages with verbose level specified directly */
-void
-xf86MsgVerb(MessageType type, int verb, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- LogVMessageVerb(type, verb, format, ap);
- va_end(ap);
-}
-
-/* Print non-driver messages with verbose level of 1 (default) */
-void
-xf86Msg(MessageType type, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- LogVMessageVerb(type, 1, format, ap);
- va_end(ap);
-}
-
-/* Just like ErrorF, but with the verbose level checked */
-void
-xf86ErrorFVerb(int verb, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- if (xf86Verbose >= verb || xf86LogVerbose >= verb)
- LogVWrite(verb, format, ap);
- va_end(ap);
-}
-
-/* Like xf86ErrorFVerb, but with an implied verbose level of 1 */
-void
-xf86ErrorF(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- if (xf86Verbose >= 1 || xf86LogVerbose >= 1)
- LogVWrite(1, format, ap);
- va_end(ap);
-}
-
-
-void
-xf86LogInit(void)
-{
- char *lf = NULL;
-
-#define LOGSUFFIX ".log"
-#define LOGOLDSUFFIX ".old"
-
- /* Get the log file name */
- if (xf86LogFileFrom == X_DEFAULT) {
- /* Append the display number and ".log" */
- if (asprintf(&lf, "%s%%s" LOGSUFFIX, xf86LogFile) == -1)
- FatalError("Cannot allocate space for the log file name\n");
- xf86LogFile = lf;
- }
-
- xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX);
- xf86LogFileWasOpened = TRUE;
-
- xf86SetVerbosity(xf86Verbose);
- xf86SetLogVerbosity(xf86LogVerbose);
-
-#undef LOGSUFFIX
-#undef LOGOLDSUFFIX
-
- free(lf);
-}
-
-void
-xf86CloseLog(void)
-{
- LogClose();
-}
-
-
-/*
- * Drivers can use these for using their own SymTabRecs.
- */
-
-const char *
-xf86TokenToString(SymTabPtr table, int token)
-{
- int i;
-
- for (i = 0; table[i].token >= 0 && table[i].token != token; i++)
- ;
-
- if (table[i].token < 0)
- return NULL;
- else
- return table[i].name;
-}
-
-int
-xf86StringToToken(SymTabPtr table, const char *string)
-{
- int i;
-
- if (string == NULL)
- return -1;
-
- for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++)
- ;
-
- return table[i].token;
-}
-
-/*
- * helper to display the clocks found on a card
- */
-void
-xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)
-{
- int j;
-
- xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:");
- for (j=0; j < scrp->numClocks; j++) {
- if ((j % 4) == 0) {
- xf86ErrorF("\n");
- xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:");
- }
- xf86ErrorF(" %7.3f", (double)scrp->clock[j] / 1000.0);
- }
- xf86ErrorF("\n");
-}
-
-
-/*
- * This prints out the driver identify message, including the names of
- * the supported chipsets.
- *
- * XXX This makes assumptions about the line width, etc. Maybe we could
- * use a more general "pretty print" function for messages.
- */
-void
-xf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips)
-{
- int len, i;
-
- len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2;
- xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg);
- for (i = 0; chips[i].name != NULL; i++) {
- if (i != 0) {
- xf86ErrorF(",");
- len++;
- }
- if (len + 2 + strlen(chips[i].name) < 78) {
- xf86ErrorF(" ");
- len++;
- } else {
- xf86ErrorF("\n\t");
- len = 8;
- }
- xf86ErrorF("%s", chips[i].name);
- len += strlen(chips[i].name);
- }
- xf86ErrorF("\n");
-}
-
-
-int
-xf86MatchDevice(const char *drivername, GDevPtr **sectlist)
-{
- GDevPtr gdp, *pgdp = NULL;
- confScreenPtr screensecptr;
- int i,j;
-
- if (sectlist)
- *sectlist = NULL;
-
- /*
- * This can happen when running Xorg -showopts and a module like ati
- * or vmware tries to load its submodules when xf86ConfigLayout is empty
- */
- if (!xf86ConfigLayout.screens)
- return 0;
-
- /*
- * This is a very important function that matches the device sections
- * as they show up in the config file with the drivers that the server
- * loads at run time.
- *
- * ChipProbe can call
- * int xf86MatchDevice(char * drivername, GDevPtr ** sectlist)
- * with its driver name. The function allocates an array of GDevPtr and
- * returns this via sectlist and returns the number of elements in
- * this list as return value. 0 means none found, -1 means fatal error.
- *
- * It can figure out which of the Device sections to use for which card
- * (using things like the Card statement, etc). For single headed servers
- * there will of course be just one such Device section.
- */
- i = 0;
-
- /*
- * first we need to loop over all the Screens sections to get to all
- * 'active' device sections
- */
- for (j=0; xf86ConfigLayout.screens[j].screen != NULL; j++) {
- screensecptr = xf86ConfigLayout.screens[j].screen;
- if ((screensecptr->device->driver != NULL)
- && (xf86NameCmp( screensecptr->device->driver,drivername) == 0)
- && (! screensecptr->device->claimed)) {
- /*
- * we have a matching driver that wasn't claimed, yet
- */
- pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
- pgdp[i++] = screensecptr->device;
- }
- }
-
- /* Then handle the inactive devices */
- j = 0;
- while (xf86ConfigLayout.inactives[j].identifier) {
- gdp = &xf86ConfigLayout.inactives[j];
- if (gdp->driver && !gdp->claimed &&
- !xf86NameCmp(gdp->driver,drivername)) {
- /* we have a matching driver that wasn't claimed yet */
- pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
- pgdp[i++] = gdp;
- }
- j++;
- }
-
- /*
- * make the array NULL terminated and return its address
- */
- if (i)
- pgdp[i] = NULL;
-
- if (sectlist)
- *sectlist = pgdp;
- else
- free(pgdp);
- return i;
-}
-
-/*
- * xf86GetClocks -- get the dot-clocks via a BIG BAD hack ...
- */
-void
-xf86GetClocks(ScrnInfoPtr pScrn, int num, Bool (*ClockFunc)(ScrnInfoPtr, int),
- void (*ProtectRegs)(ScrnInfoPtr, Bool),
- void (*BlankScreen)(ScrnInfoPtr, Bool), IOADDRESS vertsyncreg,
- int maskval, int knownclkindex, int knownclkvalue)
-{
- register int status = vertsyncreg;
- unsigned long i, cnt, rcnt, sync;
-
- /* First save registers that get written on */
- (*ClockFunc)(pScrn, CLK_REG_SAVE);
-
- if (num > MAXCLOCKS)
- num = MAXCLOCKS;
-
- for (i = 0; i < num; i++)
- {
- if (ProtectRegs)
- (*ProtectRegs)(pScrn, TRUE);
- if (!(*ClockFunc)(pScrn, i))
- {
- pScrn->clock[i] = -1;
- continue;
- }
- if (ProtectRegs)
- (*ProtectRegs)(pScrn, FALSE);
- if (BlankScreen)
- (*BlankScreen)(pScrn, FALSE);
-
- usleep(50000); /* let VCO stabilise */
-
- cnt = 0;
- sync = 200000;
-
- while ((inb(status) & maskval) == 0x00)
- if (sync-- == 0) goto finish;
- /* Something appears to be happening, so reset sync count */
- sync = 200000;
- while ((inb(status) & maskval) == maskval)
- if (sync-- == 0) goto finish;
- /* Something appears to be happening, so reset sync count */
- sync = 200000;
- while ((inb(status) & maskval) == 0x00)
- if (sync-- == 0) goto finish;
-
- for (rcnt = 0; rcnt < 5; rcnt++)
- {
- while (!(inb(status) & maskval))
- cnt++;
- while ((inb(status) & maskval))
- cnt++;
- }
-
-finish:
- pScrn->clock[i] = cnt ? cnt : -1;
- if (BlankScreen)
- (*BlankScreen)(pScrn, TRUE);
- }
-
- for (i = 0; i < num; i++)
- {
- if (i != knownclkindex)
- {
- if (pScrn->clock[i] == -1)
- {
- pScrn->clock[i] = 0;
- }
- else
- {
- pScrn->clock[i] = (int)(0.5 +
- (((float)knownclkvalue) * pScrn->clock[knownclkindex]) /
- (pScrn->clock[i]));
- /* Round to nearest 10KHz */
- pScrn->clock[i] += 5;
- pScrn->clock[i] /= 10;
- pScrn->clock[i] *= 10;
- }
- }
- }
-
- pScrn->clock[knownclkindex] = knownclkvalue;
- pScrn->numClocks = num;
-
- /* Restore registers that were written on */
- (*ClockFunc)(pScrn, CLK_REG_RESTORE);
-}
-
-const char *
-xf86GetVisualName(int visual)
-{
- if (visual < 0 || visual > DirectColor)
- return NULL;
-
- return xf86VisualNames[visual];
-}
-
-
-int
-xf86GetVerbosity(void)
-{
- return max(xf86Verbose, xf86LogVerbose);
-}
-
-Pix24Flags
-xf86GetPix24(void)
-{
- return xf86Info.pixmap24;
-}
-
-
-int
-xf86GetDepth(void)
-{
- return xf86Depth;
-}
-
-
-rgb
-xf86GetWeight(void)
-{
- return xf86Weight;
-}
-
-
-Gamma
-xf86GetGamma(void)
-{
- return xf86Gamma;
-}
-
-
-Bool
-xf86GetFlipPixels(void)
-{
- return xf86FlipPixels;
-}
-
-
-const char *
-xf86GetServerName(void)
-{
- return xf86ServerName;
-}
-
-
-Bool
-xf86ServerIsExiting(void)
-{
- return (dispatchException & DE_TERMINATE) == DE_TERMINATE;
-}
-
-
-Bool
-xf86ServerIsResetting(void)
-{
- return xf86Resetting;
-}
-
-
-Bool
-xf86ServerIsInitialising(void)
-{
- return xf86Initialising;
-}
-
-
-Bool
-xf86ServerIsOnlyDetecting(void)
-{
- return xf86DoConfigure;
-}
-
-
-Bool
-xf86CaughtSignal(void)
-{
- return xf86Info.caughtSignal;
-}
-
-
-Bool
-xf86GetVidModeAllowNonLocal(void)
-{
- return xf86Info.vidModeAllowNonLocal;
-}
-
-
-Bool
-xf86GetVidModeEnabled(void)
-{
- return xf86Info.vidModeEnabled;
-}
-
-Bool
-xf86GetModInDevAllowNonLocal(void)
-{
- return xf86Info.miscModInDevAllowNonLocal;
-}
-
-
-Bool
-xf86GetModInDevEnabled(void)
-{
- return xf86Info.miscModInDevEnabled;
-}
-
-
-Bool
-xf86GetAllowMouseOpenFail(void)
-{
- return xf86Info.allowMouseOpenFail;
-}
-
-
-Bool
-xf86IsPc98(void)
-{
-#if SUPPORT_PC98
- return xf86Info.pc98;
-#else
- return FALSE;
-#endif
-}
-
-void
-xf86DisableRandR(void)
-{
- xf86Info.disableRandR = TRUE;
- xf86Info.randRFrom = X_PROBED;
-}
-
-CARD32
-xf86GetModuleVersion(pointer module)
-{
- return (CARD32)LoaderGetModuleVersion(module);
-}
-
-pointer
-xf86LoadDrvSubModule(DriverPtr drv, const char *name)
-{
- pointer ret;
- int errmaj = 0, errmin = 0;
-
- ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
- &errmaj, &errmin);
- if (!ret)
- LoaderErrorMsg(NULL, name, errmaj, errmin);
- return ret;
-}
-
-pointer
-xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)
-{
- pointer ret;
- int errmaj = 0, errmin = 0;
-
- ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL,
- &errmaj, &errmin);
- if (!ret)
- LoaderErrorMsg(pScrn->name, name, errmaj, errmin);
- return ret;
-}
-
-/*
- * xf86LoadOneModule loads a single module.
- */
-pointer
-xf86LoadOneModule(char *name, pointer opt)
-{
- int errmaj, errmin;
- char *Name;
- pointer mod;
-
- if (!name)
- return NULL;
-
- /* Normalise the module name */
- Name = xf86NormalizeName(name);
-
- /* Skip empty names */
- if (Name == NULL)
- return NULL;
- if (*Name == '\0') {
- free(Name);
- return NULL;
- }
-
- mod = LoadModule(Name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin);
- if (!mod)
- LoaderErrorMsg(NULL, Name, errmaj, errmin);
- free(Name);
- return mod;
-}
-
-void
-xf86UnloadSubModule(pointer mod)
-{
- /*
- * This is disabled for now. The loader isn't smart enough yet to undo
- * relocations.
- */
-#if 0
- UnloadSubModule(mod);
-#endif
-}
-
-Bool
-xf86LoaderCheckSymbol(const char *name)
-{
- return LoaderSymbol(name) != NULL;
-}
-
-typedef enum {
- OPTION_BACKING_STORE
-} BSOpts;
-
-static const OptionInfoRec BSOptions[] = {
- { OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL, OPTV_NONE, {0}, FALSE }
-};
-
-void
-xf86SetBackingStore(ScreenPtr pScreen)
-{
- Bool useBS = FALSE;
- MessageType from = X_DEFAULT;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- OptionInfoPtr options;
-
- options = xnfalloc(sizeof(BSOptions));
- (void)memcpy(options, BSOptions, sizeof(BSOptions));
- xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
-
- /* check for commandline option here */
- if (xf86bsEnableFlag) {
- from = X_CMDLINE;
- useBS = TRUE;
- } else if (xf86bsDisableFlag) {
- from = X_CMDLINE;
- useBS = FALSE;
- } else {
- if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS))
- from = X_CONFIG;
- }
- free(options);
- pScreen->backingStoreSupport = useBS ? Always : NotUseful;
- if (serverGeneration == 1)
- xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n",
- useBS ? "enabled" : "disabled");
-}
-
-
-typedef enum {
- OPTION_SILKEN_MOUSE
-} SMOpts;
-
-static const OptionInfoRec SMOptions[] = {
- { OPTION_SILKEN_MOUSE, "SilkenMouse", OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL, OPTV_NONE, {0}, FALSE }
-};
-
-void
-xf86SetSilkenMouse (ScreenPtr pScreen)
-{
- Bool useSM = TRUE;
- MessageType from = X_DEFAULT;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- OptionInfoPtr options;
-
- options = xnfalloc(sizeof(SMOptions));
- (void)memcpy(options, SMOptions, sizeof(SMOptions));
- xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
-
- /* check for commandline option here */
- /* disable if screen shares resources */
- /* TODO VGA arb disable silken mouse */
- if (xf86silkenMouseDisableFlag) {
- from = X_CMDLINE;
- useSM = FALSE;
- } else {
- if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM))
- from = X_CONFIG;
- }
- free(options);
- /*
- * XXX quick hack to report correctly for OSs that can't do SilkenMouse
- * yet. Should handle this differently so that alternate async methods
- * work correctly with this too.
- */
- pScrn->silkenMouse = useSM && xf86Info.useSIGIO && xf86SIGIOSupported();
- if (serverGeneration == 1)
- xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n",
- pScrn->silkenMouse ? "enabled" : "disabled");
-}
-
-/* Wrote this function for the PM2 Xv driver, preliminary. */
-
-pointer
-xf86FindXvOptions(int scrnIndex, int adaptor_index, char *port_name,
- char **adaptor_name, pointer *adaptor_options)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- confXvAdaptorPtr adaptor;
- int i;
-
- if (adaptor_index >= pScrn->confScreen->numxvadaptors) {
- if (adaptor_name) *adaptor_name = NULL;
- if (adaptor_options) *adaptor_options = NULL;
- return NULL;
- }
-
- adaptor = &pScrn->confScreen->xvadaptors[adaptor_index];
- if (adaptor_name) *adaptor_name = adaptor->identifier;
- if (adaptor_options) *adaptor_options = adaptor->options;
-
- for (i = 0; i < adaptor->numports; i++)
- if (!xf86NameCmp(adaptor->ports[i].identifier, port_name))
- return adaptor->ports[i].options;
-
- return NULL;
-}
-
-/* Rather than duplicate loader's get OS function, just include it directly */
-#define LoaderGetOS xf86GetOS
-#include "loader/os.c"
-
-static void
-xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
- EntityProc enter, EntityProc leave, pointer private)
-{
- ScrnInfoPtr pScrn;
-
- if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
- xf86RemoveEntityFromScreen(pScrn,pEnt->index);
- xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
-}
-
-ScrnInfoPtr
-xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
- EntityProc init, EntityProc enter, EntityProc leave,
- pointer private)
-{
- EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
- if (!pEnt) return pScrn;
-
- if (!(pEnt->location.type == BUS_NONE)) {
- free(pEnt);
- return pScrn;
- }
-
- if (!pEnt->active) {
- xf86ConfigFbEntityInactive(pEnt, init, enter, leave, private);
- free(pEnt);
- return pScrn;
- }
-
- if (!pScrn)
- pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag);
- xf86AddEntityToScreen(pScrn,entityIndex);
-
- xf86SetEntityFuncs(entityIndex,init,enter,leave,private);
-
- free(pEnt);
- return pScrn;
-}
-
-Bool
-xf86IsScreenPrimary(int scrnIndex)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- int i;
-
- for (i=0 ; i < pScrn->numEntities; i++) {
- if (xf86IsEntityPrimary(i))
- return TRUE;
- }
- return FALSE;
-}
-
-int
-xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
- int format, unsigned long len, pointer value )
-{
- RootWinPropPtr pNewProp = NULL, pRegProp;
- int i;
- Bool existing = FALSE;
-
- DebugF("xf86RegisterRootWindowProperty(%d, %ld, %ld, %d, %ld, %p)\n",
- ScrnIndex, property, type, format, len, value);
-
- if (ScrnIndex<0 || ScrnIndex>=xf86NumScreens) {
- return BadMatch;
- }
-
- if (xf86RegisteredPropertiesTable &&
- xf86RegisteredPropertiesTable[ScrnIndex]) {
- for (pNewProp = xf86RegisteredPropertiesTable[ScrnIndex];
- pNewProp; pNewProp = pNewProp->next) {
- if (strcmp(pNewProp->name, NameForAtom(property)) == 0)
- break;
- }
- }
-
- if (!pNewProp) {
- if ((pNewProp = (RootWinPropPtr)malloc(sizeof(RootWinProp))) == NULL) {
- return BadAlloc;
- }
- /*
- * We will put this property at the end of the list so that
- * the changes are made in the order they were requested.
- */
- pNewProp->next = NULL;
- } else {
- free(pNewProp->name);
- existing = TRUE;
- }
-
- pNewProp->name = xnfstrdup(NameForAtom(property));
- pNewProp->type = type;
- pNewProp->format = format;
- pNewProp->size = len;
- pNewProp->data = value;
-
- DebugF("new property filled\n");
-
- if (NULL==xf86RegisteredPropertiesTable) {
- DebugF("creating xf86RegisteredPropertiesTable[] size %d\n",
- xf86NumScreens);
- if ( NULL==(xf86RegisteredPropertiesTable=(RootWinPropPtr*)xnfcalloc(sizeof(RootWinProp),xf86NumScreens) )) {
- return BadAlloc;
- }
- for (i=0; i<xf86NumScreens; i++) {
- xf86RegisteredPropertiesTable[i] = NULL;
- }
- }
-
- DebugF("xf86RegisteredPropertiesTable %p\n",
- (void *)xf86RegisteredPropertiesTable);
- DebugF("xf86RegisteredPropertiesTable[%d] %p\n",
- ScrnIndex, (void *)xf86RegisteredPropertiesTable[ScrnIndex]);
-
- if (!existing) {
- if ( xf86RegisteredPropertiesTable[ScrnIndex] == NULL) {
- xf86RegisteredPropertiesTable[ScrnIndex] = pNewProp;
- } else {
- pRegProp = xf86RegisteredPropertiesTable[ScrnIndex];
- while (pRegProp->next != NULL) {
- DebugF("- next %p\n", (void *)pRegProp);
- pRegProp = pRegProp->next;
- }
- pRegProp->next = pNewProp;
- }
- }
- DebugF("xf86RegisterRootWindowProperty succeeded\n");
- return Success;
-}
-
-Bool
-xf86IsUnblank(int mode)
-{
- switch(mode) {
- case SCREEN_SAVER_OFF:
- case SCREEN_SAVER_FORCER:
- return TRUE;
- case SCREEN_SAVER_ON:
- case SCREEN_SAVER_CYCLE:
- return FALSE;
- default:
- xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode);
- return TRUE;
- }
-}
-
-void
-xf86MotionHistoryAllocate(InputInfoPtr pInfo)
-{
- AllocateMotionHistory(pInfo->dev);
-}
+/*
+ * Copyright (c) 1997-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).
+ */
+
+/*
+ * Authors: Dirk Hohndel <hohndel@XFree86.Org>
+ * David Dawes <dawes@XFree86.Org>
+ * ... and others
+ *
+ * This file includes the helper functions that the server provides for
+ * different drivers.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include "os.h"
+#include "servermd.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#include "gcstruct.h"
+#include "loaderProcs.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "micmap.h"
+#include "xf86DDC.h"
+#include "xf86Xinput.h"
+#include "xf86InPriv.h"
+#include "mivalidate.h"
+#include "xf86Crtc.h"
+
+/* For xf86GetClocks */
+#if defined(CSRG_BASED) || defined(__GNU__)
+#define HAS_SETPRIORITY
+#include <sys/resource.h>
+#endif
+
+static int xf86ScrnInfoPrivateCount = 0;
+
+
+/* Add a pointer to a new DriverRec to xf86DriverList */
+
+void
+xf86AddDriver(DriverPtr driver, pointer module, int flags)
+{
+ /* Don't add null entries */
+ if (!driver)
+ return;
+
+ if (xf86DriverList == NULL)
+ xf86NumDrivers = 0;
+
+ xf86NumDrivers++;
+ xf86DriverList = xnfrealloc(xf86DriverList,
+ xf86NumDrivers * sizeof(DriverPtr));
+ xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec));
+ if (flags & HaveDriverFuncs)
+ *xf86DriverList[xf86NumDrivers - 1] = *driver;
+ else {
+ (void) memset( xf86DriverList[xf86NumDrivers - 1], 0,
+ sizeof( DriverRec ) );
+ (void) memcpy( xf86DriverList[xf86NumDrivers - 1], driver,
+ sizeof(DriverRec1));
+
+ }
+ xf86DriverList[xf86NumDrivers - 1]->module = module;
+ xf86DriverList[xf86NumDrivers - 1]->refCount = 0;
+}
+
+void
+xf86DeleteDriver(int drvIndex)
+{
+ if (xf86DriverList[drvIndex]
+ && (!xf86DriverHasEntities(xf86DriverList[drvIndex]))) {
+ if (xf86DriverList[drvIndex]->module)
+ UnloadModule(xf86DriverList[drvIndex]->module);
+ free(xf86DriverList[drvIndex]);
+ xf86DriverList[drvIndex] = NULL;
+ }
+}
+
+/* Add a pointer to a new InputDriverRec to xf86InputDriverList */
+
+void
+xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags)
+{
+ /* Don't add null entries */
+ if (!driver)
+ return;
+
+ if (xf86InputDriverList == NULL)
+ xf86NumInputDrivers = 0;
+
+ xf86NumInputDrivers++;
+ xf86InputDriverList = xnfrealloc(xf86InputDriverList,
+ xf86NumInputDrivers * sizeof(InputDriverPtr));
+ xf86InputDriverList[xf86NumInputDrivers - 1] =
+ xnfalloc(sizeof(InputDriverRec));
+ *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver;
+ xf86InputDriverList[xf86NumInputDrivers - 1]->module = module;
+}
+
+void
+xf86DeleteInputDriver(int drvIndex)
+{
+ if (xf86InputDriverList[drvIndex] && xf86InputDriverList[drvIndex]->module)
+ UnloadModule(xf86InputDriverList[drvIndex]->module);
+ free(xf86InputDriverList[drvIndex]);
+ xf86InputDriverList[drvIndex] = NULL;
+}
+
+InputDriverPtr
+xf86LookupInputDriver(const char *name)
+{
+ int i;
+
+ for (i = 0; i < xf86NumInputDrivers; i++) {
+ if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName &&
+ xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0)
+ return xf86InputDriverList[i];
+ }
+ return NULL;
+}
+
+InputInfoPtr
+xf86LookupInput(const char *name)
+{
+ InputInfoPtr p;
+
+ for (p = xf86InputDevs; p != NULL; p = p->next) {
+ if (strcmp(name, p->name) == 0)
+ return p;
+ }
+
+ return NULL;
+}
+
+/* Allocate a new ScrnInfoRec in xf86Screens */
+
+ScrnInfoPtr
+xf86AllocateScreen(DriverPtr drv, int flags)
+{
+ int i;
+
+ if (xf86Screens == NULL)
+ xf86NumScreens = 0;
+
+ i = xf86NumScreens++;
+ xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
+ xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
+ xf86Screens[i]->scrnIndex = i; /* Changes when a screen is removed */
+ xf86Screens[i]->origIndex = i; /* This never changes */
+ xf86Screens[i]->privates = xnfcalloc(sizeof(DevUnion),
+ xf86ScrnInfoPrivateCount);
+ /*
+ * EnableDisableFBAccess now gets initialized in InitOutput()
+ * xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
+ */
+
+ xf86Screens[i]->drv = drv;
+ drv->refCount++;
+ xf86Screens[i]->module = DuplicateModule(drv->module, NULL);
+
+ xf86Screens[i]->DriverFunc = drv->driverFunc;
+
+ return xf86Screens[i];
+}
+
+
+/*
+ * Remove an entry from xf86Screens. Ideally it should free all allocated
+ * data. To do this properly may require a driver hook.
+ */
+
+void
+xf86DeleteScreen(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn;
+ int i;
+
+ /* First check if the screen is valid */
+ if (xf86NumScreens == 0 || xf86Screens == NULL)
+ return;
+
+ if (scrnIndex > xf86NumScreens - 1)
+ return;
+
+ if (!(pScrn = xf86Screens[scrnIndex]))
+ return;
+
+ /* If a FreeScreen function is defined, call it here */
+ if (pScrn->FreeScreen != NULL)
+ pScrn->FreeScreen(scrnIndex, 0);
+
+ while (pScrn->modes)
+ xf86DeleteMode(&pScrn->modes, pScrn->modes);
+
+ while (pScrn->modePool)
+ xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
+
+ xf86OptionListFree(pScrn->options);
+
+ if (pScrn->module)
+ UnloadModule(pScrn->module);
+
+ if (pScrn->drv)
+ pScrn->drv->refCount--;
+
+ free(pScrn->privates);
+
+ xf86ClearEntityListForScreen(scrnIndex);
+
+ free(pScrn);
+
+ /* Move the other entries down, updating their scrnIndex fields */
+
+ xf86NumScreens--;
+
+ for (i = scrnIndex; i < xf86NumScreens; i++) {
+ xf86Screens[i] = xf86Screens[i + 1];
+ xf86Screens[i]->scrnIndex = i;
+ /* Also need to take care of the screen layout settings */
+ }
+}
+
+/*
+ * Allocate a private in ScrnInfoRec.
+ */
+
+int
+xf86AllocateScrnInfoPrivateIndex(void)
+{
+ int idx, i;
+ ScrnInfoPtr pScr;
+ DevUnion *nprivs;
+
+ idx = xf86ScrnInfoPrivateCount++;
+ for (i = 0; i < xf86NumScreens; i++) {
+ pScr = xf86Screens[i];
+ nprivs = xnfrealloc(pScr->privates,
+ xf86ScrnInfoPrivateCount * sizeof(DevUnion));
+ /* Zero the new private */
+ memset(&nprivs[idx], 0, sizeof(DevUnion));
+ pScr->privates = nprivs;
+ }
+ return idx;
+}
+
+Bool
+xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad)
+{
+ int i;
+
+ if (pScrn->numFormats >= MAXFORMATS)
+ return FALSE;
+
+ if (bpp <= 0) {
+ if (depth == 1)
+ bpp = 1;
+ else if (depth <= 8)
+ bpp = 8;
+ else if (depth <= 16)
+ bpp = 16;
+ else if (depth <= 32)
+ bpp = 32;
+ else
+ return FALSE;
+ }
+ if (pad <= 0)
+ pad = BITMAP_SCANLINE_PAD;
+
+ i = pScrn->numFormats++;
+ pScrn->formats[i].depth = depth;
+ pScrn->formats[i].bitsPerPixel = bpp;
+ pScrn->formats[i].scanlinePad = pad;
+ return TRUE;
+}
+
+/*
+ * Set the depth we are using based on (in the following order of preference):
+ * - values given on the command line
+ * - values given in the config file
+ * - values provided by the driver
+ * - an overall default when nothing else is given
+ *
+ * Also find a Display subsection matching the depth/bpp found.
+ *
+ * Sets the following ScrnInfoRec fields:
+ * bitsPerPixel, pixmap24, depth, display, imageByteOrder,
+ * bitmapScanlinePad, bitmapScanlineUnit, bitmapBitOrder, numFormats,
+ * formats, fbFormat.
+ */
+
+/* Can the screen handle 24 bpp pixmaps */
+#define DO_PIX24(f) ((f & Support24bppFb) || \
+ ((f & Support32bppFb) && (f & SupportConvert24to32)))
+
+/* Can the screen handle 32 bpp pixmaps */
+#define DO_PIX32(f) ((f & Support32bppFb) || \
+ ((f & Support24bppFb) && (f & SupportConvert32to24)))
+
+/* Does the screen prefer 32bpp fb for 24bpp pixmaps */
+#define CHOOSE32FOR24(f) ((f & Support32bppFb) && (f & SupportConvert24to32) \
+ && (f & PreferConvert24to32))
+
+/* Does the screen prefer 24bpp fb for 32bpp pixmaps */
+#define CHOOSE24FOR32(f) ((f & Support24bppFb) && (f & SupportConvert32to24) \
+ && (f & PreferConvert32to24))
+
+/* Can the screen handle 32bpp pixmaps for 24bpp fb */
+#define DO_PIX32FOR24(f) ((f & Support24bppFb) && (f & SupportConvert32to24))
+
+/* Can the screen handle 24bpp pixmaps for 32bpp fb */
+#define DO_PIX24FOR32(f) ((f & Support32bppFb) && (f & SupportConvert24to32))
+
+#ifndef GLOBAL_DEFAULT_DEPTH
+#define GLOBAL_DEFAULT_DEPTH 24
+#endif
+
+Bool
+xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
+ int depth24flags)
+{
+ int i;
+ DispPtr disp;
+ Pix24Flags pix24 = xf86Info.pixmap24;
+ Bool nomatch = FALSE;
+
+ scrp->bitsPerPixel = -1;
+ scrp->depth = -1;
+ scrp->pixmap24 = Pix24DontCare;
+ scrp->bitsPerPixelFrom = X_DEFAULT;
+ scrp->depthFrom = X_DEFAULT;
+
+ if (xf86FbBpp > 0) {
+ scrp->bitsPerPixel = xf86FbBpp;
+ scrp->bitsPerPixelFrom = X_CMDLINE;
+ }
+
+ if (xf86Depth > 0) {
+ scrp->depth = xf86Depth;
+ scrp->depthFrom = X_CMDLINE;
+ }
+
+ if (xf86FbBpp < 0 && xf86Depth < 0) {
+ if (scrp->confScreen->defaultfbbpp > 0) {
+ scrp->bitsPerPixel = scrp->confScreen->defaultfbbpp;
+ scrp->bitsPerPixelFrom = X_CONFIG;
+ }
+ if (scrp->confScreen->defaultdepth > 0) {
+ scrp->depth = scrp->confScreen->defaultdepth;
+ scrp->depthFrom = X_CONFIG;
+ }
+
+ if (scrp->confScreen->defaultfbbpp <= 0 &&
+ scrp->confScreen->defaultdepth <= 0) {
+ /*
+ * Check for DefaultDepth and DefaultFbBpp options in the
+ * Device sections.
+ */
+ int i;
+ GDevPtr device;
+ Bool found = FALSE;
+
+ for (i = 0; i < scrp->numEntities; i++) {
+ device = xf86GetDevFromEntity(scrp->entityList[i],
+ scrp->entityInstanceList[i]);
+ if (device && device->options) {
+ if (xf86FindOption(device->options, "DefaultDepth")) {
+ scrp->depth = xf86SetIntOption(device->options,
+ "DefaultDepth", -1);
+ scrp->depthFrom = X_CONFIG;
+ found = TRUE;
+ }
+ if (xf86FindOption(device->options, "DefaultFbBpp")) {
+ scrp->bitsPerPixel = xf86SetIntOption(device->options,
+ "DefaultFbBpp",
+ -1);
+ scrp->bitsPerPixelFrom = X_CONFIG;
+ found = TRUE;
+ }
+ }
+ if (found)
+ break;
+ }
+ }
+ }
+
+ /* If none of these is set, pick a default */
+ if (scrp->bitsPerPixel < 0 && scrp->depth < 0) {
+ if (fbbpp > 0 || depth > 0) {
+ if (fbbpp > 0)
+ scrp->bitsPerPixel = fbbpp;
+ if (depth > 0)
+ scrp->depth = depth;
+ } else {
+ scrp->depth = GLOBAL_DEFAULT_DEPTH;
+ }
+ }
+
+ /* If any are not given, determine a default for the others */
+
+ if (scrp->bitsPerPixel < 0) {
+ /* The depth must be set */
+ if (scrp->depth > -1) {
+ if (scrp->depth == 1)
+ scrp->bitsPerPixel = 1;
+ else if (scrp->depth <= 4)
+ scrp->bitsPerPixel = 4;
+ else if (scrp->depth <= 8)
+ scrp->bitsPerPixel = 8;
+ else if (scrp->depth <= 16)
+ scrp->bitsPerPixel = 16;
+ else if (scrp->depth <= 24) {
+ /*
+ * Figure out if a choice is possible based on the depth24
+ * and pix24 flags.
+ */
+ /* Check pix24 first */
+ if (pix24 != Pix24DontCare) {
+ if (pix24 == Pix24Use32) {
+ if (DO_PIX32(depth24flags)) {
+ if (CHOOSE24FOR32(depth24flags))
+ scrp->bitsPerPixel = 24;
+ else
+ scrp->bitsPerPixel = 32;
+ } else {
+ nomatch = TRUE;
+ }
+ } else if (pix24 == Pix24Use24) {
+ if (DO_PIX24(depth24flags)) {
+ if (CHOOSE32FOR24(depth24flags))
+ scrp->bitsPerPixel = 32;
+ else
+ scrp->bitsPerPixel = 24;
+ } else {
+ nomatch = TRUE;
+ }
+ }
+ } else {
+ if (DO_PIX32(depth24flags)) {
+ if (CHOOSE24FOR32(depth24flags))
+ scrp->bitsPerPixel = 24;
+ else
+ scrp->bitsPerPixel = 32;
+ } else if (DO_PIX24(depth24flags)) {
+ if (CHOOSE32FOR24(depth24flags))
+ scrp->bitsPerPixel = 32;
+ else
+ scrp->bitsPerPixel = 24;
+ }
+ }
+ } else if (scrp->depth <= 32)
+ scrp->bitsPerPixel = 32;
+ else {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Specified depth (%d) is greater than 32\n",
+ scrp->depth);
+ return FALSE;
+ }
+ } else {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "xf86SetDepthBpp: internal error: depth and fbbpp"
+ " are both not set\n");
+ return FALSE;
+ }
+ if (scrp->bitsPerPixel < 0) {
+ if (nomatch)
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Driver can't support depth 24 pixmap format (%d)\n",
+ PIX24TOBPP(pix24));
+ else if ((depth24flags & (Support24bppFb | Support32bppFb)) ==
+ NoDepth24Support)
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Driver can't support depth 24\n");
+ else
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Can't find fbbpp for depth 24\n");
+ return FALSE;
+ }
+ scrp->bitsPerPixelFrom = X_PROBED;
+ }
+
+ if (scrp->depth <= 0) {
+ /* bitsPerPixel is already set */
+ switch (scrp->bitsPerPixel) {
+ case 32:
+ scrp->depth = 24;
+ break;
+ default:
+ /* 1, 4, 8, 16 and 24 */
+ scrp->depth = scrp->bitsPerPixel;
+ break;
+ }
+ scrp->depthFrom = X_PROBED;
+ }
+
+ /* Sanity checks */
+ if (scrp->depth < 1 || scrp->depth > 32) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Specified depth (%d) is not in the range 1-32\n",
+ scrp->depth);
+ return FALSE;
+ }
+ switch (scrp->bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ break;
+ default:
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Specified fbbpp (%d) is not a permitted value\n",
+ scrp->bitsPerPixel);
+ return FALSE;
+ }
+ if (scrp->depth > scrp->bitsPerPixel) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Specified depth (%d) is greater than the fbbpp (%d)\n",
+ scrp->depth, scrp->bitsPerPixel);
+ return FALSE;
+ }
+
+ /* set scrp->pixmap24 if the driver isn't flexible */
+ if (scrp->bitsPerPixel == 24 && !DO_PIX32FOR24(depth24flags)) {
+ scrp->pixmap24 = Pix24Use24;
+ }
+ if (scrp->bitsPerPixel == 32 && !DO_PIX24FOR32(depth24flags)) {
+ scrp->pixmap24 = Pix24Use32;
+ }
+
+ /*
+ * Find the Display subsection matching the depth/fbbpp and initialise
+ * scrp->display with it.
+ */
+ for (i = 0, disp = scrp->confScreen->displays;
+ i < scrp->confScreen->numdisplays; i++, disp++) {
+ if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel)
+ || (disp->depth == scrp->depth && disp->fbbpp <= 0)
+ || (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) {
+ scrp->display = disp;
+ break;
+ }
+ }
+
+ /*
+ * If an exact match can't be found, see if there is one with no
+ * depth or fbbpp specified.
+ */
+ if (i == scrp->confScreen->numdisplays) {
+ for (i = 0, disp = scrp->confScreen->displays;
+ i < scrp->confScreen->numdisplays; i++, disp++) {
+ if (disp->depth <= 0 && disp->fbbpp <= 0) {
+ scrp->display = disp;
+ break;
+ }
+ }
+ }
+
+ /*
+ * If all else fails, create a default one.
+ */
+ if (i == scrp->confScreen->numdisplays) {
+ scrp->confScreen->numdisplays++;
+ scrp->confScreen->displays =
+ xnfrealloc(scrp->confScreen->displays,
+ scrp->confScreen->numdisplays * sizeof(DispRec));
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "Creating default Display subsection in Screen section\n"
+ "\t\"%s\" for depth/fbbpp %d/%d\n",
+ scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel);
+ memset(&scrp->confScreen->displays[i], 0, sizeof(DispRec));
+ scrp->confScreen->displays[i].blackColour.red = -1;
+ scrp->confScreen->displays[i].blackColour.green = -1;
+ scrp->confScreen->displays[i].blackColour.blue = -1;
+ scrp->confScreen->displays[i].whiteColour.red = -1;
+ scrp->confScreen->displays[i].whiteColour.green = -1;
+ scrp->confScreen->displays[i].whiteColour.blue = -1;
+ scrp->confScreen->displays[i].defaultVisual = -1;
+ scrp->confScreen->displays[i].modes = xnfalloc(sizeof(char *));
+ scrp->confScreen->displays[i].modes[0] = NULL;
+ scrp->confScreen->displays[i].depth = depth;
+ scrp->confScreen->displays[i].fbbpp = fbbpp;
+ scrp->display = &scrp->confScreen->displays[i];
+ }
+
+ /*
+ * Setup defaults for the display-wide attributes the framebuffer will
+ * need. These defaults should eventually be set globally, and not
+ * dependent on the screens.
+ */
+ scrp->imageByteOrder = IMAGE_BYTE_ORDER;
+ scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+ if (scrp->depth < 8) {
+ /* Planar modes need these settings */
+ scrp->bitmapScanlineUnit = 8;
+ scrp->bitmapBitOrder = MSBFirst;
+ } else {
+ scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ scrp->bitmapBitOrder = BITMAP_BIT_ORDER;
+ }
+
+ /*
+ * If an unusual depth is required, add it to scrp->formats. The formats
+ * for the common depths are handled globally in InitOutput
+ */
+ switch (scrp->depth) {
+ case 1:
+ case 4:
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ /* Common depths. Nothing to do for them */
+ break;
+ default:
+ if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Can't add pixmap format for depth %d\n", scrp->depth);
+ return FALSE;
+ }
+ }
+
+ /* Initialise the framebuffer format for this screen */
+ scrp->fbFormat.depth = scrp->depth;
+ scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel;
+ scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD;
+
+ return TRUE;
+}
+
+/*
+ * Print out the selected depth and bpp.
+ */
+void
+xf86PrintDepthBpp(ScrnInfoPtr scrp)
+{
+ xf86DrvMsg(scrp->scrnIndex, scrp->depthFrom, "Depth %d, ", scrp->depth);
+ xf86Msg(scrp->bitsPerPixelFrom, "framebuffer bpp %d\n", scrp->bitsPerPixel);
+}
+
+/*
+ * xf86SetWeight sets scrp->weight, scrp->mask, scrp->offset, and for depths
+ * greater than MAX_PSEUDO_DEPTH also scrp->rgbBits.
+ */
+Bool
+xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)
+{
+ MessageType weightFrom = X_DEFAULT;
+
+ scrp->weight.red = 0;
+ scrp->weight.green = 0;
+ scrp->weight.blue = 0;
+
+ if (xf86Weight.red > 0 && xf86Weight.green > 0 && xf86Weight.blue > 0) {
+ scrp->weight = xf86Weight;
+ weightFrom = X_CMDLINE;
+ } else if (scrp->display->weight.red > 0 && scrp->display->weight.green > 0
+ && scrp->display->weight.blue > 0) {
+ scrp->weight = scrp->display->weight;
+ weightFrom = X_CONFIG;
+ } else if (weight.red > 0 && weight.green > 0 && weight.blue > 0) {
+ scrp->weight = weight;
+ } else {
+ switch (scrp->depth) {
+ case 1:
+ case 4:
+ case 8:
+ scrp->weight.red = scrp->weight.green =
+ scrp->weight.blue = scrp->rgbBits;
+ break;
+ case 15:
+ scrp->weight.red = scrp->weight.green = scrp->weight.blue = 5;
+ break;
+ case 16:
+ scrp->weight.red = scrp->weight.blue = 5;
+ scrp->weight.green = 6;
+ break;
+ case 18:
+ scrp->weight.red = scrp->weight.green = scrp->weight.blue = 6;
+ break;
+ case 24:
+ scrp->weight.red = scrp->weight.green = scrp->weight.blue = 8;
+ break;
+ case 30:
+ scrp->weight.red = scrp->weight.green = scrp->weight.blue = 10;
+ break;
+ }
+ }
+
+ if (scrp->weight.red)
+ xf86DrvMsg(scrp->scrnIndex, weightFrom, "RGB weight %d%d%d\n",
+ (int)scrp->weight.red, (int)scrp->weight.green,
+ (int)scrp->weight.blue);
+
+ if (scrp->depth > MAX_PSEUDO_DEPTH &&
+ (scrp->depth != scrp->weight.red + scrp->weight.green +
+ scrp->weight.blue)) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Weight given (%d%d%d) is inconsistent with the "
+ "depth (%d)\n",
+ (int)scrp->weight.red, (int)scrp->weight.green,
+ (int)scrp->weight.blue, scrp->depth);
+ return FALSE;
+ }
+ if (scrp->depth > MAX_PSEUDO_DEPTH && scrp->weight.red) {
+ /*
+ * XXX Does this even mean anything for TrueColor visuals?
+ * If not, we shouldn't even be setting it here. However, this
+ * matches the behaviour of 3.x versions of XFree86.
+ */
+ scrp->rgbBits = scrp->weight.red;
+ if (scrp->weight.green > scrp->rgbBits)
+ scrp->rgbBits = scrp->weight.green;
+ if (scrp->weight.blue > scrp->rgbBits)
+ scrp->rgbBits = scrp->weight.blue;
+ }
+
+ /* Set the mask and offsets */
+ if (mask.red == 0 || mask.green == 0 || mask.blue == 0) {
+ /* Default to a setting common to PC hardware */
+ scrp->offset.red = scrp->weight.green + scrp->weight.blue;
+ scrp->offset.green = scrp->weight.blue;
+ scrp->offset.blue = 0;
+ scrp->mask.red = ((1 << scrp->weight.red) - 1) << scrp->offset.red;
+ scrp->mask.green = ((1 << scrp->weight.green) - 1)
+ << scrp->offset.green;
+ scrp->mask.blue = (1 << scrp->weight.blue) - 1;
+ } else {
+ /* Initialise to the values passed */
+ scrp->mask.red = mask.red;
+ scrp->mask.green = mask.green;
+ scrp->mask.blue = mask.blue;
+ scrp->offset.red = ffs(mask.red);
+ scrp->offset.green = ffs(mask.green);
+ scrp->offset.blue = ffs(mask.blue);
+ }
+ return TRUE;
+}
+
+Bool
+xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)
+{
+ MessageType visualFrom = X_DEFAULT;
+
+ if (defaultColorVisualClass >= 0) {
+ scrp->defaultVisual = defaultColorVisualClass;
+ visualFrom = X_CMDLINE;
+ } else if (scrp->display->defaultVisual >= 0) {
+ scrp->defaultVisual = scrp->display->defaultVisual;
+ visualFrom = X_CONFIG;
+ } else if (visual >= 0) {
+ scrp->defaultVisual = visual;
+ } else {
+ if (scrp->depth == 1)
+ scrp->defaultVisual = StaticGray;
+ else if (scrp->depth == 4)
+ scrp->defaultVisual = StaticColor;
+ else if (scrp->depth <= MAX_PSEUDO_DEPTH)
+ scrp->defaultVisual = PseudoColor;
+ else
+ scrp->defaultVisual = TrueColor;
+ }
+ switch (scrp->defaultVisual) {
+ case StaticGray:
+ case GrayScale:
+ case StaticColor:
+ case PseudoColor:
+ case TrueColor:
+ case DirectColor:
+ xf86DrvMsg(scrp->scrnIndex, visualFrom, "Default visual is %s\n",
+ xf86VisualNames[scrp->defaultVisual]);
+ return TRUE;
+ default:
+
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Invalid default visual class (%d)\n", scrp->defaultVisual);
+ return FALSE;
+ }
+}
+
+#define TEST_GAMMA(g) \
+ (g).red > GAMMA_ZERO || (g).green > GAMMA_ZERO || (g).blue > GAMMA_ZERO
+
+#define SET_GAMMA(g) \
+ (g) > GAMMA_ZERO ? (g) : 1.0
+
+Bool
+xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)
+{
+ MessageType from = X_DEFAULT;
+#if 0
+ xf86MonPtr DDC = (xf86MonPtr)(scrp->monitor->DDC);
+#endif
+ if (TEST_GAMMA(xf86Gamma)) {
+ from = X_CMDLINE;
+ scrp->gamma.red = SET_GAMMA(xf86Gamma.red);
+ scrp->gamma.green = SET_GAMMA(xf86Gamma.green);
+ scrp->gamma.blue = SET_GAMMA(xf86Gamma.blue);
+ } else if (TEST_GAMMA(scrp->monitor->gamma)) {
+ from = X_CONFIG;
+ scrp->gamma.red = SET_GAMMA(scrp->monitor->gamma.red);
+ scrp->gamma.green = SET_GAMMA(scrp->monitor->gamma.green);
+ scrp->gamma.blue = SET_GAMMA(scrp->monitor->gamma.blue);
+#if 0
+ } else if ( DDC && DDC->features.gamma > GAMMA_ZERO ) {
+ from = X_PROBED;
+ scrp->gamma.red = SET_GAMMA(DDC->features.gamma);
+ scrp->gamma.green = SET_GAMMA(DDC->features.gamma);
+ scrp->gamma.blue = SET_GAMMA(DDC->features.gamma);
+ /* EDID structure version 2 gives optional seperate red, green & blue gamma values
+ * in bytes 0x57-0x59 */
+#endif
+ } else if (TEST_GAMMA(gamma)) {
+ scrp->gamma.red = SET_GAMMA(gamma.red);
+ scrp->gamma.green = SET_GAMMA(gamma.green);
+ scrp->gamma.blue = SET_GAMMA(gamma.blue);
+ } else {
+ scrp->gamma.red = 1.0;
+ scrp->gamma.green = 1.0;
+ scrp->gamma.blue = 1.0;
+ }
+ /* Pretend we succeeded if we support better a gamma system.
+ * This avoids a confusing message.
+ */
+ if (xf86_crtc_supports_gamma(scrp))
+ return TRUE;
+ xf86DrvMsg(scrp->scrnIndex, from,
+ "Using gamma correction (%.1f, %.1f, %.1f)\n",
+ scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue);
+
+ return TRUE;
+}
+
+#undef TEST_GAMMA
+#undef SET_GAMMA
+
+
+/*
+ * Set the DPI from the command line option. XXX should allow it to be
+ * calculated from the widthmm/heightmm values.
+ */
+
+#undef MMPERINCH
+#define MMPERINCH 25.4
+
+void
+xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
+{
+ MessageType from = X_DEFAULT;
+ xf86MonPtr DDC = (xf86MonPtr)(pScrn->monitor->DDC);
+ int ddcWidthmm, ddcHeightmm;
+ int widthErr, heightErr;
+
+ /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
+ pScrn->widthmm = pScrn->monitor->widthmm;
+ pScrn->heightmm = pScrn->monitor->heightmm;
+
+ if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0) ) {
+ /* DDC gives display size in mm for individual modes,
+ * but cm for monitor
+ */
+ ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
+ ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
+ } else {
+ ddcWidthmm = ddcHeightmm = 0;
+ }
+
+ if (monitorResolution > 0) {
+ pScrn->xDpi = monitorResolution;
+ pScrn->yDpi = monitorResolution;
+ from = X_CMDLINE;
+ } else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) {
+ from = X_CONFIG;
+ if (pScrn->widthmm > 0) {
+ pScrn->xDpi =
+ (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
+ }
+ if (pScrn->heightmm > 0) {
+ pScrn->yDpi =
+ (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
+ }
+ if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
+ pScrn->yDpi = pScrn->xDpi;
+ if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
+ pScrn->xDpi = pScrn->yDpi;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
+ pScrn->widthmm, pScrn->heightmm);
+
+ /* Warn if config and probe disagree about display size */
+ if ( ddcWidthmm && ddcHeightmm ) {
+ if (pScrn->widthmm > 0) {
+ widthErr = abs(ddcWidthmm - pScrn->widthmm);
+ } else {
+ widthErr = 0;
+ }
+ if (pScrn->heightmm > 0) {
+ heightErr = abs(ddcHeightmm - pScrn->heightmm);
+ } else {
+ heightErr = 0;
+ }
+ if (widthErr>10 || heightErr>10) {
+ /* Should include config file name for monitor here */
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
+ ddcWidthmm,ddcHeightmm, pScrn->widthmm,pScrn->heightmm);
+ }
+ }
+ } else if ( ddcWidthmm && ddcHeightmm ) {
+ from = X_PROBED;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
+ ddcWidthmm, ddcHeightmm );
+ pScrn->widthmm = ddcWidthmm;
+ pScrn->heightmm = ddcHeightmm;
+ if (pScrn->widthmm > 0) {
+ pScrn->xDpi =
+ (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
+ }
+ if (pScrn->heightmm > 0) {
+ pScrn->yDpi =
+ (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
+ }
+ if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
+ pScrn->yDpi = pScrn->xDpi;
+ if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
+ pScrn->xDpi = pScrn->yDpi;
+ } else {
+ if (x > 0)
+ pScrn->xDpi = x;
+ else
+ pScrn->xDpi = DEFAULT_DPI;
+ if (y > 0)
+ pScrn->yDpi = y;
+ else
+ pScrn->yDpi = DEFAULT_DPI;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "DPI set to (%d, %d)\n",
+ pScrn->xDpi, pScrn->yDpi);
+}
+
+#undef MMPERINCH
+
+
+void
+xf86SetBlackWhitePixels(ScreenPtr pScreen)
+{
+ if (xf86FlipPixels) {
+ pScreen->whitePixel = 0;
+ pScreen->blackPixel = 1;
+ } else {
+ pScreen->whitePixel = 1;
+ pScreen->blackPixel = 0;
+ }
+}
+
+/*
+ * Function to enable/disable access to the frame buffer
+ *
+ * This is used when VT switching and when entering/leaving DGA direct mode.
+ *
+ * This has been rewritten again to eliminate the saved pixmap. The
+ * devPrivate field in the screen pixmap is set to NULL to catch code
+ * accidentally referencing the frame buffer while the X server is not
+ * supposed to touch it.
+ *
+ * Here, we exchange the pixmap private data, rather than the pixmaps
+ * themselves to avoid having to find and change any references to the screen
+ * pixmap such as GC's, window privates etc. This also means that this code
+ * does not need to know exactly how the pixmap pixels are accessed. Further,
+ * this exchange is >not< done through the screen's ModifyPixmapHeader()
+ * vector. This means the called frame buffer code layers can determine
+ * whether they are switched in or out by keeping track of the root pixmap's
+ * private data, and therefore don't need to access pScrnInfo->vtSema.
+ */
+void
+xf86EnableDisableFBAccess(int scrnIndex, Bool enable)
+{
+ ScrnInfoPtr pScrnInfo = xf86Screens[scrnIndex];
+ ScreenPtr pScreen = pScrnInfo->pScreen;
+ PixmapPtr pspix;
+
+ pspix = (*pScreen->GetScreenPixmap) (pScreen);
+ if (enable)
+ {
+ /*
+ * Restore all of the clip lists on the screen
+ */
+ if (!xf86Resetting)
+ SetRootClip (pScreen, TRUE);
+
+ }
+ else
+ {
+ /*
+ * Empty all of the clip lists on the screen
+ */
+ SetRootClip (pScreen, FALSE);
+ }
+}
+
+/* Print driver messages in the standard format */
+
+#undef PREFIX_SIZE
+#define PREFIX_SIZE 14
+
+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
+ LogVMessageVerb(type, verb, format, args);
+}
+#undef PREFIX_SIZE
+
+/* Print driver messages, with verbose level specified directly */
+void
+xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
+ ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap);
+ va_end(ap);
+}
+
+/* Print driver messages, with verbose level of 1 (default) */
+void
+xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap);
+ va_end(ap);
+}
+
+/* Print input driver messages in the standard format of
+ <driver>: <device name>: <message> */
+void
+xf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format,
+ va_list args)
+{
+ char *msg;
+
+ 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);
+ }
+}
+
+/* Print input driver message, with verbose level specified directly */
+void
+xf86IDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format,
+ ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xf86VIDrvMsgVerb(dev, type, verb, format, ap);
+ va_end(ap);
+}
+
+/* Print input driver messages, with verbose level of 1 (default) */
+void
+xf86IDrvMsg(InputInfoPtr dev, MessageType type, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xf86VIDrvMsgVerb(dev, type, 1, format, ap);
+ va_end(ap);
+}
+
+
+/* Print non-driver messages with verbose level specified directly */
+void
+xf86MsgVerb(MessageType type, int verb, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ LogVMessageVerb(type, verb, format, ap);
+ va_end(ap);
+}
+
+/* Print non-driver messages with verbose level of 1 (default) */
+void
+xf86Msg(MessageType type, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ LogVMessageVerb(type, 1, format, ap);
+ va_end(ap);
+}
+
+/* Just like ErrorF, but with the verbose level checked */
+void
+xf86ErrorFVerb(int verb, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ if (xf86Verbose >= verb || xf86LogVerbose >= verb)
+ LogVWrite(verb, format, ap);
+ va_end(ap);
+}
+
+/* Like xf86ErrorFVerb, but with an implied verbose level of 1 */
+void
+xf86ErrorF(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ if (xf86Verbose >= 1 || xf86LogVerbose >= 1)
+ LogVWrite(1, format, ap);
+ va_end(ap);
+}
+
+
+void
+xf86LogInit(void)
+{
+ char *lf = NULL;
+
+#define LOGSUFFIX ".log"
+#define LOGOLDSUFFIX ".old"
+
+ /* Get the log file name */
+ if (xf86LogFileFrom == X_DEFAULT) {
+ /* Append the display number and ".log" */
+ if (asprintf(&lf, "%s%%s" LOGSUFFIX, xf86LogFile) == -1)
+ FatalError("Cannot allocate space for the log file name\n");
+ xf86LogFile = lf;
+ }
+
+ xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX);
+ xf86LogFileWasOpened = TRUE;
+
+ xf86SetVerbosity(xf86Verbose);
+ xf86SetLogVerbosity(xf86LogVerbose);
+
+#undef LOGSUFFIX
+#undef LOGOLDSUFFIX
+
+ free(lf);
+}
+
+void
+xf86CloseLog(void)
+{
+ LogClose();
+}
+
+
+/*
+ * Drivers can use these for using their own SymTabRecs.
+ */
+
+const char *
+xf86TokenToString(SymTabPtr table, int token)
+{
+ int i;
+
+ for (i = 0; table[i].token >= 0 && table[i].token != token; i++)
+ ;
+
+ if (table[i].token < 0)
+ return NULL;
+ else
+ return table[i].name;
+}
+
+int
+xf86StringToToken(SymTabPtr table, const char *string)
+{
+ int i;
+
+ if (string == NULL)
+ return -1;
+
+ for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++)
+ ;
+
+ return table[i].token;
+}
+
+/*
+ * helper to display the clocks found on a card
+ */
+void
+xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)
+{
+ int j;
+
+ xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:");
+ for (j=0; j < scrp->numClocks; j++) {
+ if ((j % 4) == 0) {
+ xf86ErrorF("\n");
+ xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:");
+ }
+ xf86ErrorF(" %7.3f", (double)scrp->clock[j] / 1000.0);
+ }
+ xf86ErrorF("\n");
+}
+
+
+/*
+ * This prints out the driver identify message, including the names of
+ * the supported chipsets.
+ *
+ * XXX This makes assumptions about the line width, etc. Maybe we could
+ * use a more general "pretty print" function for messages.
+ */
+void
+xf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips)
+{
+ int len, i;
+
+ len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2;
+ xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg);
+ for (i = 0; chips[i].name != NULL; i++) {
+ if (i != 0) {
+ xf86ErrorF(",");
+ len++;
+ }
+ if (len + 2 + strlen(chips[i].name) < 78) {
+ xf86ErrorF(" ");
+ len++;
+ } else {
+ xf86ErrorF("\n\t");
+ len = 8;
+ }
+ xf86ErrorF("%s", chips[i].name);
+ len += strlen(chips[i].name);
+ }
+ xf86ErrorF("\n");
+}
+
+
+int
+xf86MatchDevice(const char *drivername, GDevPtr **sectlist)
+{
+ GDevPtr gdp, *pgdp = NULL;
+ confScreenPtr screensecptr;
+ int i,j;
+
+ if (sectlist)
+ *sectlist = NULL;
+
+ /*
+ * This can happen when running Xorg -showopts and a module like ati
+ * or vmware tries to load its submodules when xf86ConfigLayout is empty
+ */
+ if (!xf86ConfigLayout.screens)
+ return 0;
+
+ /*
+ * This is a very important function that matches the device sections
+ * as they show up in the config file with the drivers that the server
+ * loads at run time.
+ *
+ * ChipProbe can call
+ * int xf86MatchDevice(char * drivername, GDevPtr ** sectlist)
+ * with its driver name. The function allocates an array of GDevPtr and
+ * returns this via sectlist and returns the number of elements in
+ * this list as return value. 0 means none found, -1 means fatal error.
+ *
+ * It can figure out which of the Device sections to use for which card
+ * (using things like the Card statement, etc). For single headed servers
+ * there will of course be just one such Device section.
+ */
+ i = 0;
+
+ /*
+ * first we need to loop over all the Screens sections to get to all
+ * 'active' device sections
+ */
+ for (j=0; xf86ConfigLayout.screens[j].screen != NULL; j++) {
+ screensecptr = xf86ConfigLayout.screens[j].screen;
+ if ((screensecptr->device->driver != NULL)
+ && (xf86NameCmp( screensecptr->device->driver,drivername) == 0)
+ && (! screensecptr->device->claimed)) {
+ /*
+ * we have a matching driver that wasn't claimed, yet
+ */
+ pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
+ pgdp[i++] = screensecptr->device;
+ }
+ }
+
+ /* Then handle the inactive devices */
+ j = 0;
+ while (xf86ConfigLayout.inactives[j].identifier) {
+ gdp = &xf86ConfigLayout.inactives[j];
+ if (gdp->driver && !gdp->claimed &&
+ !xf86NameCmp(gdp->driver,drivername)) {
+ /* we have a matching driver that wasn't claimed yet */
+ pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
+ pgdp[i++] = gdp;
+ }
+ j++;
+ }
+
+ /*
+ * make the array NULL terminated and return its address
+ */
+ if (i)
+ pgdp[i] = NULL;
+
+ if (sectlist)
+ *sectlist = pgdp;
+ else
+ free(pgdp);
+ return i;
+}
+
+/*
+ * xf86GetClocks -- get the dot-clocks via a BIG BAD hack ...
+ */
+void
+xf86GetClocks(ScrnInfoPtr pScrn, int num, Bool (*ClockFunc)(ScrnInfoPtr, int),
+ void (*ProtectRegs)(ScrnInfoPtr, Bool),
+ void (*BlankScreen)(ScrnInfoPtr, Bool), IOADDRESS vertsyncreg,
+ int maskval, int knownclkindex, int knownclkvalue)
+{
+ register int status = vertsyncreg;
+ unsigned long i, cnt, rcnt, sync;
+
+ /* First save registers that get written on */
+ (*ClockFunc)(pScrn, CLK_REG_SAVE);
+
+ if (num > MAXCLOCKS)
+ num = MAXCLOCKS;
+
+ for (i = 0; i < num; i++)
+ {
+ if (ProtectRegs)
+ (*ProtectRegs)(pScrn, TRUE);
+ if (!(*ClockFunc)(pScrn, i))
+ {
+ pScrn->clock[i] = -1;
+ continue;
+ }
+ if (ProtectRegs)
+ (*ProtectRegs)(pScrn, FALSE);
+ if (BlankScreen)
+ (*BlankScreen)(pScrn, FALSE);
+
+ usleep(50000); /* let VCO stabilise */
+
+ cnt = 0;
+ sync = 200000;
+
+ while ((inb(status) & maskval) == 0x00)
+ if (sync-- == 0) goto finish;
+ /* Something appears to be happening, so reset sync count */
+ sync = 200000;
+ while ((inb(status) & maskval) == maskval)
+ if (sync-- == 0) goto finish;
+ /* Something appears to be happening, so reset sync count */
+ sync = 200000;
+ while ((inb(status) & maskval) == 0x00)
+ if (sync-- == 0) goto finish;
+
+ for (rcnt = 0; rcnt < 5; rcnt++)
+ {
+ while (!(inb(status) & maskval))
+ cnt++;
+ while ((inb(status) & maskval))
+ cnt++;
+ }
+
+finish:
+ pScrn->clock[i] = cnt ? cnt : -1;
+ if (BlankScreen)
+ (*BlankScreen)(pScrn, TRUE);
+ }
+
+ for (i = 0; i < num; i++)
+ {
+ if (i != knownclkindex)
+ {
+ if (pScrn->clock[i] == -1)
+ {
+ pScrn->clock[i] = 0;
+ }
+ else
+ {
+ pScrn->clock[i] = (int)(0.5 +
+ (((float)knownclkvalue) * pScrn->clock[knownclkindex]) /
+ (pScrn->clock[i]));
+ /* Round to nearest 10KHz */
+ pScrn->clock[i] += 5;
+ pScrn->clock[i] /= 10;
+ pScrn->clock[i] *= 10;
+ }
+ }
+ }
+
+ pScrn->clock[knownclkindex] = knownclkvalue;
+ pScrn->numClocks = num;
+
+ /* Restore registers that were written on */
+ (*ClockFunc)(pScrn, CLK_REG_RESTORE);
+}
+
+const char *
+xf86GetVisualName(int visual)
+{
+ if (visual < 0 || visual > DirectColor)
+ return NULL;
+
+ return xf86VisualNames[visual];
+}
+
+
+int
+xf86GetVerbosity(void)
+{
+ return max(xf86Verbose, xf86LogVerbose);
+}
+
+Pix24Flags
+xf86GetPix24(void)
+{
+ return xf86Info.pixmap24;
+}
+
+
+int
+xf86GetDepth(void)
+{
+ return xf86Depth;
+}
+
+
+rgb
+xf86GetWeight(void)
+{
+ return xf86Weight;
+}
+
+
+Gamma
+xf86GetGamma(void)
+{
+ return xf86Gamma;
+}
+
+
+Bool
+xf86GetFlipPixels(void)
+{
+ return xf86FlipPixels;
+}
+
+
+const char *
+xf86GetServerName(void)
+{
+ return xf86ServerName;
+}
+
+
+Bool
+xf86ServerIsExiting(void)
+{
+ return (dispatchException & DE_TERMINATE) == DE_TERMINATE;
+}
+
+
+Bool
+xf86ServerIsResetting(void)
+{
+ return xf86Resetting;
+}
+
+
+Bool
+xf86ServerIsInitialising(void)
+{
+ return xf86Initialising;
+}
+
+
+Bool
+xf86ServerIsOnlyDetecting(void)
+{
+ return xf86DoConfigure;
+}
+
+
+Bool
+xf86CaughtSignal(void)
+{
+ return xf86Info.caughtSignal;
+}
+
+
+Bool
+xf86GetVidModeAllowNonLocal(void)
+{
+ return xf86Info.vidModeAllowNonLocal;
+}
+
+
+Bool
+xf86GetVidModeEnabled(void)
+{
+ return xf86Info.vidModeEnabled;
+}
+
+Bool
+xf86GetModInDevAllowNonLocal(void)
+{
+ return xf86Info.miscModInDevAllowNonLocal;
+}
+
+
+Bool
+xf86GetModInDevEnabled(void)
+{
+ return xf86Info.miscModInDevEnabled;
+}
+
+
+Bool
+xf86GetAllowMouseOpenFail(void)
+{
+ return xf86Info.allowMouseOpenFail;
+}
+
+
+Bool
+xf86IsPc98(void)
+{
+#if SUPPORT_PC98
+ return xf86Info.pc98;
+#else
+ return FALSE;
+#endif
+}
+
+void
+xf86DisableRandR(void)
+{
+ xf86Info.disableRandR = TRUE;
+ xf86Info.randRFrom = X_PROBED;
+}
+
+CARD32
+xf86GetModuleVersion(pointer module)
+{
+ return (CARD32)LoaderGetModuleVersion(module);
+}
+
+pointer
+xf86LoadDrvSubModule(DriverPtr drv, const char *name)
+{
+ pointer ret;
+ int errmaj = 0, errmin = 0;
+
+ ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
+ &errmaj, &errmin);
+ if (!ret)
+ LoaderErrorMsg(NULL, name, errmaj, errmin);
+ return ret;
+}
+
+pointer
+xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)
+{
+ pointer ret;
+ int errmaj = 0, errmin = 0;
+
+ ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL,
+ &errmaj, &errmin);
+ if (!ret)
+ LoaderErrorMsg(pScrn->name, name, errmaj, errmin);
+ return ret;
+}
+
+/*
+ * xf86LoadOneModule loads a single module.
+ */
+pointer
+xf86LoadOneModule(char *name, pointer opt)
+{
+ int errmaj, errmin;
+ char *Name;
+ pointer mod;
+
+ if (!name)
+ return NULL;
+
+ /* Normalise the module name */
+ Name = xf86NormalizeName(name);
+
+ /* Skip empty names */
+ if (Name == NULL)
+ return NULL;
+ if (*Name == '\0') {
+ free(Name);
+ return NULL;
+ }
+
+ mod = LoadModule(Name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin);
+ if (!mod)
+ LoaderErrorMsg(NULL, Name, errmaj, errmin);
+ free(Name);
+ return mod;
+}
+
+void
+xf86UnloadSubModule(pointer mod)
+{
+ /*
+ * This is disabled for now. The loader isn't smart enough yet to undo
+ * relocations.
+ */
+#if 0
+ UnloadSubModule(mod);
+#endif
+}
+
+Bool
+xf86LoaderCheckSymbol(const char *name)
+{
+ return LoaderSymbol(name) != NULL;
+}
+
+typedef enum {
+ OPTION_BACKING_STORE
+} BSOpts;
+
+static const OptionInfoRec BSOptions[] = {
+ { OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+void
+xf86SetBackingStore(ScreenPtr pScreen)
+{
+ Bool useBS = FALSE;
+ MessageType from = X_DEFAULT;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ OptionInfoPtr options;
+
+ options = xnfalloc(sizeof(BSOptions));
+ (void)memcpy(options, BSOptions, sizeof(BSOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+ /* check for commandline option here */
+ if (xf86bsEnableFlag) {
+ from = X_CMDLINE;
+ useBS = TRUE;
+ } else if (xf86bsDisableFlag) {
+ from = X_CMDLINE;
+ useBS = FALSE;
+ } else {
+ if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS))
+ from = X_CONFIG;
+ }
+ free(options);
+ pScreen->backingStoreSupport = useBS ? Always : NotUseful;
+ if (serverGeneration == 1)
+ xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n",
+ useBS ? "enabled" : "disabled");
+}
+
+
+typedef enum {
+ OPTION_SILKEN_MOUSE
+} SMOpts;
+
+static const OptionInfoRec SMOptions[] = {
+ { OPTION_SILKEN_MOUSE, "SilkenMouse", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+void
+xf86SetSilkenMouse (ScreenPtr pScreen)
+{
+ Bool useSM = TRUE;
+ MessageType from = X_DEFAULT;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ OptionInfoPtr options;
+
+ options = xnfalloc(sizeof(SMOptions));
+ (void)memcpy(options, SMOptions, sizeof(SMOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+ /* check for commandline option here */
+ /* disable if screen shares resources */
+ /* TODO VGA arb disable silken mouse */
+ if (xf86silkenMouseDisableFlag) {
+ from = X_CMDLINE;
+ useSM = FALSE;
+ } else {
+ if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM))
+ from = X_CONFIG;
+ }
+ free(options);
+ /*
+ * XXX quick hack to report correctly for OSs that can't do SilkenMouse
+ * yet. Should handle this differently so that alternate async methods
+ * work correctly with this too.
+ */
+ pScrn->silkenMouse = useSM && xf86Info.useSIGIO && xf86SIGIOSupported();
+ if (serverGeneration == 1)
+ xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n",
+ pScrn->silkenMouse ? "enabled" : "disabled");
+}
+
+/* Wrote this function for the PM2 Xv driver, preliminary. */
+
+pointer
+xf86FindXvOptions(int scrnIndex, int adaptor_index, char *port_name,
+ char **adaptor_name, pointer *adaptor_options)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ confXvAdaptorPtr adaptor;
+ int i;
+
+ if (adaptor_index >= pScrn->confScreen->numxvadaptors) {
+ if (adaptor_name) *adaptor_name = NULL;
+ if (adaptor_options) *adaptor_options = NULL;
+ return NULL;
+ }
+
+ adaptor = &pScrn->confScreen->xvadaptors[adaptor_index];
+ if (adaptor_name) *adaptor_name = adaptor->identifier;
+ if (adaptor_options) *adaptor_options = adaptor->options;
+
+ for (i = 0; i < adaptor->numports; i++)
+ if (!xf86NameCmp(adaptor->ports[i].identifier, port_name))
+ return adaptor->ports[i].options;
+
+ return NULL;
+}
+
+/* Rather than duplicate loader's get OS function, just include it directly */
+#define LoaderGetOS xf86GetOS
+#include "loader/os.c"
+
+static void
+xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
+ EntityProc enter, EntityProc leave, pointer private)
+{
+ ScrnInfoPtr pScrn;
+
+ if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
+ xf86RemoveEntityFromScreen(pScrn,pEnt->index);
+ xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
+}
+
+ScrnInfoPtr
+xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
+ EntityProc init, EntityProc enter, EntityProc leave,
+ pointer private)
+{
+ EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
+ if (!pEnt) return pScrn;
+
+ if (!(pEnt->location.type == BUS_NONE)) {
+ free(pEnt);
+ return pScrn;
+ }
+
+ if (!pEnt->active) {
+ xf86ConfigFbEntityInactive(pEnt, init, enter, leave, private);
+ free(pEnt);
+ return pScrn;
+ }
+
+ if (!pScrn)
+ pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag);
+ xf86AddEntityToScreen(pScrn,entityIndex);
+
+ xf86SetEntityFuncs(entityIndex,init,enter,leave,private);
+
+ free(pEnt);
+ return pScrn;
+}
+
+Bool
+xf86IsScreenPrimary(int scrnIndex)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ int i;
+
+ for (i=0 ; i < pScrn->numEntities; i++) {
+ if (xf86IsEntityPrimary(i))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int
+xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
+ int format, unsigned long len, pointer value )
+{
+ RootWinPropPtr pNewProp = NULL, pRegProp;
+ int i;
+ Bool existing = FALSE;
+
+ DebugF("xf86RegisterRootWindowProperty(%d, %ld, %ld, %d, %ld, %p)\n",
+ ScrnIndex, property, type, format, len, value);
+
+ if (ScrnIndex<0 || ScrnIndex>=xf86NumScreens) {
+ return BadMatch;
+ }
+
+ if (xf86RegisteredPropertiesTable &&
+ xf86RegisteredPropertiesTable[ScrnIndex]) {
+ for (pNewProp = xf86RegisteredPropertiesTable[ScrnIndex];
+ pNewProp; pNewProp = pNewProp->next) {
+ if (strcmp(pNewProp->name, NameForAtom(property)) == 0)
+ break;
+ }
+ }
+
+ if (!pNewProp) {
+ if ((pNewProp = (RootWinPropPtr)malloc(sizeof(RootWinProp))) == NULL) {
+ return BadAlloc;
+ }
+ /*
+ * We will put this property at the end of the list so that
+ * the changes are made in the order they were requested.
+ */
+ pNewProp->next = NULL;
+ } else {
+ free(pNewProp->name);
+ existing = TRUE;
+ }
+
+ pNewProp->name = xnfstrdup(NameForAtom(property));
+ pNewProp->type = type;
+ pNewProp->format = format;
+ pNewProp->size = len;
+ pNewProp->data = value;
+
+ DebugF("new property filled\n");
+
+ if (NULL==xf86RegisteredPropertiesTable) {
+ DebugF("creating xf86RegisteredPropertiesTable[] size %d\n",
+ xf86NumScreens);
+ if ( NULL==(xf86RegisteredPropertiesTable=(RootWinPropPtr*)xnfcalloc(sizeof(RootWinProp),xf86NumScreens) )) {
+ return BadAlloc;
+ }
+ for (i=0; i<xf86NumScreens; i++) {
+ xf86RegisteredPropertiesTable[i] = NULL;
+ }
+ }
+
+ DebugF("xf86RegisteredPropertiesTable %p\n",
+ (void *)xf86RegisteredPropertiesTable);
+ DebugF("xf86RegisteredPropertiesTable[%d] %p\n",
+ ScrnIndex, (void *)xf86RegisteredPropertiesTable[ScrnIndex]);
+
+ if (!existing) {
+ if ( xf86RegisteredPropertiesTable[ScrnIndex] == NULL) {
+ xf86RegisteredPropertiesTable[ScrnIndex] = pNewProp;
+ } else {
+ pRegProp = xf86RegisteredPropertiesTable[ScrnIndex];
+ while (pRegProp->next != NULL) {
+ DebugF("- next %p\n", (void *)pRegProp);
+ pRegProp = pRegProp->next;
+ }
+ pRegProp->next = pNewProp;
+ }
+ }
+ DebugF("xf86RegisterRootWindowProperty succeeded\n");
+ return Success;
+}
+
+Bool
+xf86IsUnblank(int mode)
+{
+ switch(mode) {
+ case SCREEN_SAVER_OFF:
+ case SCREEN_SAVER_FORCER:
+ return TRUE;
+ case SCREEN_SAVER_ON:
+ case SCREEN_SAVER_CYCLE:
+ return FALSE;
+ default:
+ xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode);
+ return TRUE;
+ }
+}
+
+void
+xf86MotionHistoryAllocate(InputInfoPtr pInfo)
+{
+ AllocateMotionHistory(pInfo->dev);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c
index 0b36163c0..bf72368c4 100644
--- a/xorg-server/hw/xfree86/common/xf86Init.c
+++ b/xorg-server/hw/xfree86/common/xf86Init.c
@@ -1,1499 +1,1499 @@
-/*
- * Loosely based on code bearing the following copyright:
- *
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- */
-/*
- * Copyright (c) 1992-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).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <stdlib.h>
-#include <errno.h>
-
-#undef HAS_UTSNAME
-#if !defined(WIN32)
-#define HAS_UTSNAME 1
-#include <sys/utsname.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xmd.h>
-#include <X11/Xproto.h>
-#include <X11/Xatom.h>
-#include "input.h"
-#include "servermd.h"
-#include "windowstr.h"
-#include "scrnintstr.h"
-#include "site.h"
-#include "mi.h"
-
-#include "compiler.h"
-
-#include "loaderProcs.h"
-#ifdef XFreeXDGA
-#include "dgaproc.h"
-#endif
-
-#define XF86_OS_PRIVS
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86Config.h"
-#include "xf86_OSlib.h"
-#include "xf86cmap.h"
-#include "xorgVersion.h"
-#include "xf86Build.h"
-#include "mipointer.h"
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include "xf86DDC.h"
-#include "xf86Xinput.h"
-#include "xf86InPriv.h"
-#include "picturestr.h"
-
-#include "xf86Bus.h"
-#include "xf86VGAarbiter.h"
-#include "globals.h"
-
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
-#include <hotplug.h>
-
-
-#ifdef XF86PM
-void (*xf86OSPMClose)(void) = NULL;
-#endif
-static Bool xorgHWOpenConsole = FALSE;
-
-/* Common pixmap formats */
-
-static PixmapFormatRec formats[MAXFORMATS] = {
- { 1, 1, BITMAP_SCANLINE_PAD },
- { 4, 8, BITMAP_SCANLINE_PAD },
- { 8, 8, BITMAP_SCANLINE_PAD },
- { 15, 16, BITMAP_SCANLINE_PAD },
- { 16, 16, BITMAP_SCANLINE_PAD },
- { 24, 32, BITMAP_SCANLINE_PAD },
- { 32, 32, BITMAP_SCANLINE_PAD },
-};
-static int numFormats = 7;
-static Bool formatsDone = FALSE;
-
-#ifndef OSNAME
-#define OSNAME " unknown"
-#endif
-#ifndef OSVENDOR
-#define OSVENDOR ""
-#endif
-#ifndef PRE_RELEASE
-#define PRE_RELEASE XORG_VERSION_SNAP
-#endif
-
-static void
-xf86PrintBanner(void)
-{
-#if PRE_RELEASE
- xf86ErrorFVerb(0, "\n"
- "This is a pre-release version of the X server from " XVENDORNAME ".\n"
- "It is not supported in any way.\n"
- "Bugs may be filed in the bugzilla at http://bugs.freedesktop.org/.\n"
- "Select the \"xorg\" product for bugs you find in this release.\n"
- "Before reporting bugs in pre-release versions please check the\n"
- "latest version in the X.Org Foundation git repository.\n"
- "See http://wiki.x.org/wiki/GitPage for git access instructions.\n");
-#endif
- xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d",
- XORG_VERSION_MAJOR,
- XORG_VERSION_MINOR,
- XORG_VERSION_PATCH);
-#if XORG_VERSION_SNAP > 0
- xf86ErrorFVerb(0, ".%d", XORG_VERSION_SNAP);
-#endif
-
-#if XORG_VERSION_SNAP >= 900
- /* When the minor number is 99, that signifies that the we are making
- * a release candidate for a major version. (X.0.0)
- * When the patch number is 99, that signifies that the we are making
- * a release candidate for a minor version. (X.Y.0)
- * When the patch number is < 99, then we are making a release
- * candidate for the next point release. (X.Y.Z)
- */
-#if XORG_VERSION_MINOR >= 99
- xf86ErrorFVerb(0, " (%d.0.0 RC %d)", XORG_VERSION_MAJOR+1,
- XORG_VERSION_SNAP - 900);
-#elif XORG_VERSION_PATCH == 99
- xf86ErrorFVerb(0, " (%d.%d.0 RC %d)", XORG_VERSION_MAJOR,
- XORG_VERSION_MINOR + 1, XORG_VERSION_SNAP - 900);
-#else
- xf86ErrorFVerb(0, " (%d.%d.%d RC %d)", XORG_VERSION_MAJOR,
- XORG_VERSION_MINOR, XORG_VERSION_PATCH + 1,
- XORG_VERSION_SNAP - 900);
-#endif
-#endif
-
-#ifdef XORG_CUSTOM_VERSION
- xf86ErrorFVerb(0, " (%s)", XORG_CUSTOM_VERSION);
-#endif
-#ifndef XORG_DATE
-# define XORG_DATE "Unknown"
-#endif
- xf86ErrorFVerb(0, "\nRelease Date: %s\n", XORG_DATE);
- xf86ErrorFVerb(0, "X Protocol Version %d, Revision %d\n",
- X_PROTOCOL, X_PROTOCOL_REVISION);
- xf86ErrorFVerb(0, "Build Operating System: %s %s\n", OSNAME, OSVENDOR);
-#ifdef HAS_UTSNAME
- {
- struct utsname name;
-
- /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX,
- and Irix) and Single Unix Spec 3 just say that non-negative is success.
- All agree that failure is represented by a negative number.
- */
- if (uname(&name) >= 0) {
- xf86ErrorFVerb(0, "Current Operating System: %s %s %s %s %s\n",
- name.sysname, name.nodename, name.release, name.version, name.machine);
-#ifdef linux
- do {
- char buf[80];
- int fd = open("/proc/cmdline", O_RDONLY);
- if (fd != -1) {
- xf86ErrorFVerb(0, "Kernel command line: ");
- memset(buf, 0, 80);
- while (read(fd, buf, 80) > 0) {
- xf86ErrorFVerb(0, "%.80s", buf);
- memset(buf, 0, 80);
- }
- close(fd);
- }
- } while (0);
-#endif
- }
- }
-#endif
-#if defined(BUILD_DATE) && (BUILD_DATE > 19000000)
- {
- struct tm t;
- char buf[100];
-
- memset(&t, 0, sizeof(t));
- memset(buf, 0, sizeof(buf));
- t.tm_mday = BUILD_DATE % 100;
- t.tm_mon = (BUILD_DATE / 100) % 100 - 1;
- t.tm_year = BUILD_DATE / 10000 - 1900;
-#if defined(BUILD_TIME)
- t.tm_sec = BUILD_TIME % 100;
- t.tm_min = (BUILD_TIME / 100) % 100;
- t.tm_hour = (BUILD_TIME / 10000) % 100;
- if (strftime(buf, sizeof(buf), "%d %B %Y %I:%M:%S%p", &t))
- xf86ErrorFVerb(0, "Build Date: %s\n", buf);
-#else
- if (strftime(buf, sizeof(buf), "%d %B %Y", &t))
- xf86ErrorFVerb(0, "Build Date: %s\n", buf);
-#endif
- }
-#endif
-#if defined(BUILDERSTRING)
- xf86ErrorFVerb(0, "%s \n", BUILDERSTRING);
-#endif
- xf86ErrorFVerb(0, "Current version of pixman: %s\n",
- pixman_version_string());
- xf86ErrorFVerb(0, "\tBefore reporting problems, check "
- ""__VENDORDWEBSUPPORT__"\n"
- "\tto make sure that you have the latest version.\n");
-}
-
-static void
-xf86PrintMarkers(void)
-{
- LogPrintMarkers();
-}
-
-static Bool
-xf86CreateRootWindow(WindowPtr pWin)
-{
- int ret = TRUE;
- int err = Success;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- RootWinPropPtr pProp;
- CreateWindowProcPtr CreateWindow = (CreateWindowProcPtr)
- dixLookupPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey);
-
- DebugF("xf86CreateRootWindow(%p)\n", pWin);
-
- if ( pScreen->CreateWindow != xf86CreateRootWindow ) {
- /* Can't find hook we are hung on */
- xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */,
- "xf86CreateRootWindow %p called when not in pScreen->CreateWindow %p n",
- (void *)xf86CreateRootWindow,
- (void *)pScreen->CreateWindow );
- }
-
- /* Unhook this function ... */
- pScreen->CreateWindow = CreateWindow;
- dixSetPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey, NULL);
-
- /* ... and call the previous CreateWindow fuction, if any */
- if (NULL!=pScreen->CreateWindow) {
- ret = (*pScreen->CreateWindow)(pWin);
- }
-
- /* Now do our stuff */
- if (xf86RegisteredPropertiesTable != NULL) {
- if (pWin->parent == NULL && xf86RegisteredPropertiesTable != NULL) {
- for (pProp = xf86RegisteredPropertiesTable[pScreen->myNum];
- pProp != NULL && err==Success;
- pProp = pProp->next )
- {
- Atom prop;
-
- prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE);
- err = dixChangeWindowProperty(serverClient, pWin,
- prop, pProp->type,
- pProp->format, PropModeReplace,
- pProp->size, pProp->data,
- FALSE);
- }
-
- /* Look at err */
- ret &= (err==Success);
-
- } else {
- xf86Msg(X_ERROR, "xf86CreateRootWindow unexpectedly called with "
- "non-root window %p (parent %p)\n",
- (void *)pWin, (void *)pWin->parent);
- ret = FALSE;
- }
- }
-
- DebugF("xf86CreateRootWindow() returns %d\n", ret);
- return ret;
-}
-
-
-static void
-InstallSignalHandlers(void)
-{
- /*
- * Install signal handler for unexpected signals
- */
- xf86Info.caughtSignal=FALSE;
- if (!xf86Info.notrapSignals) {
- OsRegisterSigWrapper(xf86SigWrapper);
- } else {
- signal(SIGSEGV, SIG_DFL);
- signal(SIGILL, SIG_DFL);
-#ifdef SIGEMT
- signal(SIGEMT, SIG_DFL);
-#endif
- signal(SIGFPE, SIG_DFL);
- signal(SIGBUS, SIG_DFL);
- signal(SIGSYS, SIG_DFL);
- signal(SIGXCPU, SIG_DFL);
- signal(SIGXFSZ, SIG_DFL);
- }
-}
-
-/*
- * InitOutput --
- * Initialize screenInfo for all actually accessible framebuffers.
- * That includes vt-manager setup, querying all possible devices and
- * collecting the pixmap formats.
- */
-void
-InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
-{
- int i, j, k, scr_index, was_blocked = 0;
- char **modulelist;
- pointer *optionlist;
- Pix24Flags screenpix24, pix24;
- MessageType pix24From = X_DEFAULT;
- Bool pix24Fail = FALSE;
- Bool autoconfig = FALSE;
- GDevPtr configured_device;
-
- xf86Initialising = TRUE;
-
- if (serverGeneration == 1) {
- if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
- xf86ServerName++;
- else
- xf86ServerName = argv[0];
-
- xf86PrintBanner();
- xf86PrintMarkers();
- if (xf86LogFile) {
- time_t t;
- const char *ct;
- t = time(NULL);
- ct = ctime(&t);
- xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
- xf86LogFile, ct);
- }
-
- /* Read and parse the config file */
- if (!xf86DoConfigure && !xf86DoShowOptions) {
- switch (xf86HandleConfigFile(FALSE)) {
- case CONFIG_OK:
- break;
- case CONFIG_PARSE_ERROR:
- xf86Msg(X_ERROR, "Error parsing the config file\n");
- return;
- case CONFIG_NOFILE:
- autoconfig = TRUE;
- break;
- }
- }
-
- InstallSignalHandlers();
-
- /* Initialise the loader */
- LoaderInit();
-
- /* Tell the loader the default module search path */
- LoaderSetPath(xf86ModulePath);
-
- if (xf86Info.ignoreABI) {
- LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
- }
-
- if (xf86DoShowOptions)
- DoShowOptions();
-
- /* Do a general bus probe. This will be a PCI probe for x86 platforms */
- xf86BusProbe();
-
- if (xf86DoConfigure)
- DoConfigure();
-
- if (autoconfig) {
- if (!xf86AutoConfig()) {
- xf86Msg(X_ERROR, "Auto configuration failed\n");
- return;
- }
- }
-
-#ifdef XF86PM
- xf86OSPMClose = xf86OSPMOpen();
-#endif
-
- /* Load all modules specified explicitly in the config file */
- if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
- xf86LoadModules(modulelist, optionlist);
- free(modulelist);
- free(optionlist);
- }
-
- /* Load all driver modules specified in the config file */
- /* If there aren't any specified in the config file, autoconfig them */
- /* FIXME: Does not handle multiple active screen sections, but I'm not
- * sure if we really want to handle that case*/
- configured_device = xf86ConfigLayout.screens->screen->device;
- if ((!configured_device) || (!configured_device->driver)) {
- if (!autoConfigDevice(configured_device)) {
- xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
- return ;
- }
- }
- if ((modulelist = xf86DriverlistFromConfig())) {
- xf86LoadModules(modulelist, NULL);
- free(modulelist);
- }
-
- /* Load all input driver modules specified in the config file. */
- if ((modulelist = xf86InputDriverlistFromConfig())) {
- xf86LoadModules(modulelist, NULL);
- free(modulelist);
- }
-
- /*
- * It is expected that xf86AddDriver()/xf86AddInputDriver will be
- * called for each driver as it is loaded. Those functions save the
- * module pointers for drivers.
- * XXX Nothing keeps track of them for other modules.
- */
- /* XXX What do we do if not all of these could be loaded? */
-
- /*
- * At this point, xf86DriverList[] is all filled in with entries for
- * each of the drivers to try and xf86NumDrivers has the number of
- * drivers. If there are none, return now.
- */
-
- if (xf86NumDrivers == 0) {
- xf86Msg(X_ERROR, "No drivers available.\n");
- return;
- }
-
- /*
- * Call each of the Identify functions and call the driverFunc to check
- * if HW access is required. The Identify functions print out some
- * identifying information, and anything else that might be
- * needed at this early stage.
- */
-
- for (i = 0; i < xf86NumDrivers; i++) {
- if (xf86DriverList[i]->Identify != NULL)
- xf86DriverList[i]->Identify(0);
-
- if (!xorgHWAccess || !xorgHWOpenConsole) {
- xorgHWFlags flags;
- if(!xf86DriverList[i]->driverFunc
- || !xf86DriverList[i]->driverFunc(NULL,
- GET_REQUIRED_HW_INTERFACES,
- &flags))
- flags = HW_IO;
-
- if(NEED_IO_ENABLED(flags))
- xorgHWAccess = TRUE;
- if(!(flags & HW_SKIP_CONSOLE))
- xorgHWOpenConsole = TRUE;
- }
- }
-
- if (xorgHWOpenConsole)
- xf86OpenConsole();
- else
- xf86Info.dontVTSwitch = TRUE;
-
- if (xf86BusConfig() == FALSE)
- return;
-
- xf86PostProbe();
-
- /*
- * Sort the drivers to match the requested ording. Using a slow
- * bubble sort.
- */
- for (j = 0; j < xf86NumScreens - 1; j++) {
- for (i = 0; i < xf86NumScreens - j - 1; i++) {
- if (xf86Screens[i + 1]->confScreen->screennum <
- xf86Screens[i]->confScreen->screennum) {
- ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
- xf86Screens[i + 1] = xf86Screens[i];
- xf86Screens[i] = tmpScrn;
- }
- }
- }
- /* Fix up the indexes */
- for (i = 0; i < xf86NumScreens; i++) {
- xf86Screens[i]->scrnIndex = i;
- }
-
- /*
- * Call the driver's PreInit()'s to complete initialisation for the first
- * generation.
- */
-
- for (i = 0; i < xf86NumScreens; i++) {
- xf86VGAarbiterScrnInit(xf86Screens[i]);
- xf86VGAarbiterLock(xf86Screens[i]);
- if (xf86Screens[i]->PreInit &&
- xf86Screens[i]->PreInit(xf86Screens[i], 0))
- xf86Screens[i]->configured = TRUE;
- xf86VGAarbiterUnlock(xf86Screens[i]);
- }
- for (i = 0; i < xf86NumScreens; i++)
- if (!xf86Screens[i]->configured)
- xf86DeleteScreen(i--, 0);
-
- /*
- * If no screens left, return now.
- */
-
- if (xf86NumScreens == 0) {
- xf86Msg(X_ERROR,
- "Screen(s) found, but none have a usable configuration.\n");
- return;
- }
-
- for (i = 0; i < xf86NumScreens; i++) {
- if (xf86Screens[i]->name == NULL) {
- XNFasprintf(&xf86Screens[i]->name, "screen%d", i);
- xf86MsgVerb(X_WARNING, 0,
- "Screen driver %d has no name set, using `%s'.\n",
- i, xf86Screens[i]->name);
- }
- }
-
- /* Remove (unload) drivers that are not required */
- for (i = 0; i < xf86NumDrivers; i++)
- if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
- xf86DeleteDriver(i);
-
- /*
- * At this stage we know how many screens there are.
- */
-
- for (i = 0; i < xf86NumScreens; i++)
- xf86InitViewport(xf86Screens[i]);
-
- /*
- * Collect all pixmap formats and check for conflicts at the display
- * level. Should we die here? Or just delete the offending screens?
- */
- screenpix24 = Pix24DontCare;
- for (i = 0; i < xf86NumScreens; i++) {
- if (xf86Screens[i]->imageByteOrder !=
- xf86Screens[0]->imageByteOrder)
- FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
- if (xf86Screens[i]->bitmapScanlinePad !=
- xf86Screens[0]->bitmapScanlinePad)
- FatalError("Inconsistent display bitmapScanlinePad. Exiting\n");
- if (xf86Screens[i]->bitmapScanlineUnit !=
- xf86Screens[0]->bitmapScanlineUnit)
- FatalError("Inconsistent display bitmapScanlineUnit. Exiting\n");
- if (xf86Screens[i]->bitmapBitOrder !=
- xf86Screens[0]->bitmapBitOrder)
- FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
-
- /* Determine the depth 24 pixmap format the screens would like */
- if (xf86Screens[i]->pixmap24 != Pix24DontCare) {
- if (screenpix24 == Pix24DontCare)
- screenpix24 = xf86Screens[i]->pixmap24;
- else if (screenpix24 != xf86Screens[i]->pixmap24)
- FatalError("Inconsistent depth 24 pixmap format. Exiting\n");
- }
- }
- /* check if screenpix24 is consistent with the config/cmdline */
- if (xf86Info.pixmap24 != Pix24DontCare) {
- pix24 = xf86Info.pixmap24;
- pix24From = xf86Info.pix24From;
- if (screenpix24 != Pix24DontCare && screenpix24 != xf86Info.pixmap24)
- pix24Fail = TRUE;
- } else if (screenpix24 != Pix24DontCare) {
- pix24 = screenpix24;
- pix24From = X_PROBED;
- } else
- pix24 = Pix24Use32;
-
- if (pix24Fail)
- FatalError("Screen(s) can't use the required depth 24 pixmap format"
- " (%d). Exiting\n", PIX24TOBPP(pix24));
-
- /* Initialise the depth 24 format */
- for (j = 0; j < numFormats && formats[j].depth != 24; j++)
- ;
- formats[j].bitsPerPixel = PIX24TOBPP(pix24);
-
- /* Collect additional formats */
- for (i = 0; i < xf86NumScreens; i++) {
- for (j = 0; j < xf86Screens[i]->numFormats; j++) {
- for (k = 0; ; k++) {
- if (k >= numFormats) {
- if (k >= MAXFORMATS)
- FatalError("Too many pixmap formats! Exiting\n");
- formats[k] = xf86Screens[i]->formats[j];
- numFormats++;
- break;
- }
- if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
- if ((formats[k].bitsPerPixel ==
- xf86Screens[i]->formats[j].bitsPerPixel) &&
- (formats[k].scanlinePad ==
- xf86Screens[i]->formats[j].scanlinePad))
- break;
- FatalError("Inconsistent pixmap format for depth %d."
- " Exiting\n", formats[k].depth);
- }
- }
- }
- }
- formatsDone = TRUE;
-
- if (xf86Info.vtno >= 0 ) {
-#define VT_ATOM_NAME "XFree86_VT"
- Atom VTAtom=-1;
- CARD32 *VT = NULL;
- int ret;
-
- /* This memory needs to stay available until the screen has been
- initialized, and we can create the property for real.
- */
- if ( (VT = malloc(sizeof(CARD32)))==NULL ) {
- FatalError("Unable to make VT property - out of memory. Exiting...\n");
- }
- *VT = xf86Info.vtno;
-
- VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
-
- for (i = 0, ret = Success; i < xf86NumScreens && ret == Success; i++) {
- ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
- VTAtom, XA_INTEGER, 32,
- 1, VT );
- if (ret != Success)
- xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
- "Failed to register VT 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) {
- xf86Msg(pix24From, "Depth 24 pixmap format is %d bpp\n",
- PIX24TOBPP(pix24));
- break;
- }
- }
- } else {
- /*
- * serverGeneration != 1; some OSs have to do things here, too.
- */
- if (xorgHWOpenConsole)
- xf86OpenConsole();
-
-#ifdef XF86PM
- /*
- should we reopen it here? We need to deal with an already opened
- device. We could leave this to the OS layer. For now we simply
- close it here
- */
- if (xf86OSPMClose)
- xf86OSPMClose();
- if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
- xf86MsgVerb(X_INFO, 3, "APM registered successfully\n");
-#endif
-
- /* Make sure full I/O access is enabled */
- if (xorgHWAccess)
- xf86EnableIO();
- }
-
- /*
- * Use the previously collected parts to setup pScreenInfo
- */
-
- pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
- pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
- pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
- pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
- pScreenInfo->numPixmapFormats = numFormats;
- for (i = 0; i < numFormats; i++)
- pScreenInfo->formats[i] = formats[i];
-
- /* Make sure the server's VT is active */
-
- if (serverGeneration != 1) {
- xf86Resetting = TRUE;
- /* All screens are in the same state, so just check the first */
- if (!xf86Screens[0]->vtSema) {
-#ifdef HAS_USL_VTS
- ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
-#endif
- xf86AccessEnter();
- was_blocked = xf86BlockSIGIO();
- }
- }
-
- for (i = 0; i < xf86NumScreens; i++)
- if (!xf86ColormapAllocatePrivates(xf86Screens[i]))
- FatalError("Cannot register DDX private keys");
-
- if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0) ||
- !dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0))
- FatalError("Cannot register DDX private keys");
-
- for (i = 0; i < xf86NumScreens; i++) {
- xf86VGAarbiterLock(xf86Screens[i]);
- /*
- * Almost everything uses these defaults, and many of those that
- * don't, will wrap them.
- */
- xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
-#ifdef XFreeXDGA
- xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
-#endif
- xf86Screens[i]->DPMSSet = NULL;
- xf86Screens[i]->LoadPalette = NULL;
- xf86Screens[i]->SetOverscan = NULL;
- xf86Screens[i]->DriverFunc = NULL;
- xf86Screens[i]->pScreen = NULL;
- scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
- xf86VGAarbiterUnlock(xf86Screens[i]);
- if (scr_index == i) {
- /*
- * Hook in our ScrnInfoRec, and initialise some other pScreen
- * fields.
- */
- dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
- xf86ScreenKey, xf86Screens[i]);
- xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
- /* The driver should set this, but make sure it is set anyway */
- xf86Screens[i]->vtSema = TRUE;
- } else {
- /* This shouldn't normally happen */
- FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
- }
-
- DebugF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
- i, xf86Screens[i]->pScreen );
- DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
- i, xf86Screens[i]->pScreen->CreateWindow );
-
- dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
- xf86CreateRootWindowKey,
- xf86Screens[i]->pScreen->CreateWindow);
- xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;
-
- if (PictureGetSubpixelOrder (xf86Screens[i]->pScreen) == SubPixelUnknown)
- {
- xf86MonPtr DDC = (xf86MonPtr)(xf86Screens[i]->monitor->DDC);
- PictureSetSubpixelOrder (xf86Screens[i]->pScreen,
- DDC ?
- (DDC->features.input_type ?
- SubPixelHorizontalRGB : SubPixelNone) :
- SubPixelUnknown);
- }
-#ifdef RANDR
- if (!xf86Info.disableRandR)
- xf86RandRInit (screenInfo.screens[scr_index]);
- xf86Msg(xf86Info.randRFrom, "RandR %s\n",
- xf86Info.disableRandR ? "disabled" : "enabled");
-#endif
- }
-
- xf86VGAarbiterWrapFunctions();
- xf86UnblockSIGIO(was_blocked);
-
- xf86InitOrigins();
-
- xf86Resetting = FALSE;
- xf86Initialising = FALSE;
-
- RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, xf86Wakeup,
- NULL);
-}
-
-/*
- * InitInput --
- * Initialize all supported input devices.
- */
-
-void
-InitInput(int argc, char **argv)
-{
- InputInfoPtr* pDev;
- DeviceIntPtr dev;
-
- xf86Info.vtRequestsPending = FALSE;
-
- mieqInit();
-
- GetEventList(&xf86Events);
-
- /* Initialize all configured input devices */
- for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) {
- /* Replace obsolete keyboard driver with kbd */
- if (!xf86NameCmp((*pDev)->driver, "keyboard")) {
- strcpy((*pDev)->driver, "kbd");
- }
-
- /* If one fails, the others will too */
- if (xf86NewInputDevice(*pDev, &dev, TRUE) == BadAlloc)
- break;
- }
-
- config_init();
-}
-
-void
-CloseInput (void)
-{
- config_fini();
-}
-
-/*
- * OsVendorInit --
- * OS/Vendor-specific initialisations. Called from OsInit(), which
- * is called by dix before establishing the well known sockets.
- */
-
-void
-OsVendorInit(void)
-{
- static Bool beenHere = FALSE;
-
- signal(SIGCHLD, SIG_DFL); /* Need to wait for child processes */
-
- if (!beenHere) {
- umask(022);
- xf86LogInit();
- }
-
- /* Set stderr to non-blocking. */
-#ifndef O_NONBLOCK
-#if defined(FNDELAY)
-#define O_NONBLOCK FNDELAY
-#elif defined(O_NDELAY)
-#define O_NONBLOCK O_NDELAY
-#endif
-
-#ifdef O_NONBLOCK
- if (!beenHere) {
- if (geteuid() == 0 && getuid() != geteuid())
- {
- int status;
-
- status = fcntl(fileno(stderr), F_GETFL, 0);
- if (status != -1) {
- fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK);
- }
- }
- }
-#endif
-#endif
-
- beenHere = TRUE;
-}
-
-/*
- * ddxGiveUp --
- * Device dependent cleanup. Called by by dix before normal server death.
- * For SYSV386 we must switch the terminal back to normal mode. No error-
- * checking here, since there should be restored as much as possible.
- */
-
-void
-ddxGiveUp(void)
-{
- int i;
-
- xf86VGAarbiterFini();
-
-#ifdef XF86PM
- if (xf86OSPMClose)
- xf86OSPMClose();
- xf86OSPMClose = NULL;
-#endif
-
- for (i = 0; i < xf86NumScreens; i++) {
- /*
- * zero all access functions to
- * trap calls when switched away.
- */
- xf86Screens[i]->vtSema = FALSE;
- }
-
-#ifdef XFreeXDGA
- DGAShutdown();
-#endif
-
- if (xorgHWOpenConsole)
- xf86CloseConsole();
-
- xf86CloseLog();
-
- /* If an unexpected signal was caught, dump a core for debugging */
- if (xf86Info.caughtSignal)
- OsAbort();
-}
-
-
-
-/*
- * AbortDDX --
- * DDX - specific abort routine. Called by AbortServer(). The attempt is
- * made to restore all original setting of the displays. Also all devices
- * are closed.
- */
-
-void
-AbortDDX(void)
-{
- int i;
-
- xf86BlockSIGIO();
-
- /*
- * try to restore the original video state
- */
-#ifdef DPMSExtension /* Turn screens back on */
- if (DPMSPowerLevel != DPMSModeOn)
- DPMSSet(serverClient, DPMSModeOn);
-#endif
- if (xf86Screens) {
- for (i = 0; i < xf86NumScreens; i++)
- if (xf86Screens[i]->vtSema) {
- /*
- * if we are aborting before ScreenInit() has finished
- * we might not have been wrapped yet. Therefore enable
- * screen explicitely.
- */
- xf86VGAarbiterLock(xf86Screens[i]);
- (xf86Screens[i]->LeaveVT)(i, 0);
- xf86VGAarbiterUnlock(xf86Screens[i]);
- }
- }
-
- xf86AccessLeave();
-
- /*
- * This is needed for an abnormal server exit, since the normal exit stuff
- * MUST also be performed (i.e. the vt must be left in a defined state)
- */
- ddxGiveUp();
-}
-
-void
-OsVendorFatalError(void)
-{
-#ifdef VENDORSUPPORT
- ErrorF("\nPlease refer to your Operating System Vendor support pages\n"
- "at %s for support on this crash.\n",VENDORSUPPORT);
-#else
- ErrorF("\nPlease consult the "XVENDORNAME" support \n"
- "\t at "__VENDORDWEBSUPPORT__"\n for help. \n");
-#endif
- if (xf86LogFile && xf86LogFileWasOpened)
- ErrorF("Please also check the log file at \"%s\" for additional "
- "information.\n", xf86LogFile);
- ErrorF("\n");
-}
-
-int
-xf86SetVerbosity(int verb)
-{
- int save = xf86Verbose;
-
- xf86Verbose = verb;
- LogSetParameter(XLOG_VERBOSITY, verb);
- return save;
-}
-
-int
-xf86SetLogVerbosity(int verb)
-{
- int save = xf86LogVerbose;
-
- xf86LogVerbose = verb;
- LogSetParameter(XLOG_FILE_VERBOSITY, verb);
- return save;
-}
-
-static void
-xf86PrintDefaultModulePath(void)
-{
- ErrorF("%s\n", DEFAULT_MODULE_PATH);
-}
-
-static void
-xf86PrintDefaultLibraryPath(void)
-{
- ErrorF("%s\n", DEFAULT_LIBRARY_PATH);
-}
-
-/*
- * ddxProcessArgument --
- * Process device-dependent command line args. Returns 0 if argument is
- * not device dependent, otherwise Count of number of elements of argv
- * that are part of a device dependent commandline option.
- *
- */
-
-/* ARGSUSED */
-int
-ddxProcessArgument(int argc, char **argv, int i)
-{
-#define CHECK_FOR_REQUIRED_ARGUMENT() \
- if (((i + 1) >= argc) || (!argv[i + 1])) { \
- ErrorF("Required argument to %s not specified\n", argv[i]); \
- UseMsg(); \
- FatalError("Required argument to %s not specified\n", argv[i]); \
- }
-
- /* First the options that are only allowed for root */
- if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) {
- if ( (geteuid() == 0) && (getuid() != 0) ) {
- FatalError("The '%s' option can only be used by root.\n", argv[i]);
- }
- else if (!strcmp(argv[i], "-modulepath"))
- {
- char *mp;
- CHECK_FOR_REQUIRED_ARGUMENT();
- mp = strdup(argv[i + 1]);
- if (!mp)
- FatalError("Can't allocate memory for ModulePath\n");
- xf86ModulePath = mp;
- xf86ModPathFrom = X_CMDLINE;
- return 2;
- }
- else if (!strcmp(argv[i], "-logfile"))
- {
- char *lf;
- CHECK_FOR_REQUIRED_ARGUMENT();
- lf = strdup(argv[i + 1]);
- if (!lf)
- FatalError("Can't allocate memory for LogFile\n");
- xf86LogFile = lf;
- xf86LogFileFrom = X_CMDLINE;
- return 2;
- }
- }
- if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
- FatalError("\nInvalid argument for %s\n"
- "\tFor non-root users, the file specified with %s must be\n"
- "\ta relative path and must not contain any \"..\" elements.\n"
- "\tUsing default "__XCONFIGFILE__" search path.\n\n",
- argv[i], argv[i]);
- }
- xf86ConfigFile = argv[i + 1];
- return 2;
- }
- if (!strcmp(argv[i], "-configdir"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
- FatalError("\nInvalid argument for %s\n"
- "\tFor non-root users, the file specified with %s must be\n"
- "\ta relative path and must not contain any \"..\" elements.\n"
- "\tUsing default "__XCONFIGDIR__" search path.\n\n",
- argv[i], argv[i]);
- }
- xf86ConfigDir = argv[i + 1];
- return 2;
- }
- if (!strcmp(argv[i],"-flipPixels"))
- {
- xf86FlipPixels = TRUE;
- return 1;
- }
-#ifdef XF86VIDMODE
- if (!strcmp(argv[i],"-disableVidMode"))
- {
- xf86VidModeDisabled = TRUE;
- return 1;
- }
- if (!strcmp(argv[i],"-allowNonLocalXvidtune"))
- {
- xf86VidModeAllowNonLocal = TRUE;
- return 1;
- }
-#endif
- if (!strcmp(argv[i],"-allowMouseOpenFail"))
- {
- xf86AllowMouseOpenFail = TRUE;
- return 1;
- }
- if (!strcmp(argv[i],"-ignoreABI"))
- {
- LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
- return 1;
- }
- if (!strcmp(argv[i],"-verbose"))
- {
- if (++i < argc && argv[i])
- {
- char *end;
- long val;
- val = strtol(argv[i], &end, 0);
- if (*end == '\0')
- {
- xf86SetVerbosity(val);
- return 2;
- }
- }
- xf86SetVerbosity(++xf86Verbose);
- return 1;
- }
- if (!strcmp(argv[i],"-logverbose"))
- {
- if (++i < argc && argv[i])
- {
- char *end;
- long val;
- val = strtol(argv[i], &end, 0);
- if (*end == '\0')
- {
- xf86SetLogVerbosity(val);
- return 2;
- }
- }
- xf86SetLogVerbosity(++xf86LogVerbose);
- return 1;
- }
- if (!strcmp(argv[i],"-quiet"))
- {
- xf86SetVerbosity(-1);
- return 1;
- }
- if (!strcmp(argv[i],"-showconfig") || !strcmp(argv[i],"-version"))
- {
- xf86PrintBanner();
- exit(0);
- }
- if (!strcmp(argv[i],"-showDefaultModulePath"))
- {
- xf86PrintDefaultModulePath();
- exit(0);
- }
- if (!strcmp(argv[i],"-showDefaultLibPath"))
- {
- xf86PrintDefaultLibraryPath();
- exit(0);
- }
- /* Notice the -fp flag, but allow it to pass to the dix layer */
- if (!strcmp(argv[i], "-fp"))
- {
- xf86fpFlag = TRUE;
- return 0;
- }
- /* Notice the -bs flag, but allow it to pass to the dix layer */
- if (!strcmp(argv[i], "-bs"))
- {
- xf86bsDisableFlag = TRUE;
- return 0;
- }
- /* Notice the +bs flag, but allow it to pass to the dix layer */
- if (!strcmp(argv[i], "+bs"))
- {
- xf86bsEnableFlag = TRUE;
- return 0;
- }
- /* Notice the -s flag, but allow it to pass to the dix layer */
- if (!strcmp(argv[i], "-s"))
- {
- xf86sFlag = TRUE;
- return 0;
- }
- if (!strcmp(argv[i], "-pixmap24"))
- {
- xf86Pix24 = Pix24Use24;
- return 1;
- }
- if (!strcmp(argv[i], "-pixmap32"))
- {
- xf86Pix24 = Pix24Use32;
- return 1;
- }
- if (!strcmp(argv[i], "-fbbpp"))
- {
- int bpp;
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (sscanf(argv[++i], "%d", &bpp) == 1)
- {
- xf86FbBpp = bpp;
- return 2;
- }
- else
- {
- ErrorF("Invalid fbbpp\n");
- return 0;
- }
- }
- if (!strcmp(argv[i], "-depth"))
- {
- int depth;
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (sscanf(argv[++i], "%d", &depth) == 1)
- {
- xf86Depth = depth;
- return 2;
- }
- else
- {
- ErrorF("Invalid depth\n");
- return 0;
- }
- }
- if (!strcmp(argv[i], "-weight"))
- {
- int red, green, blue;
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3)
- {
- xf86Weight.red = red;
- xf86Weight.green = green;
- xf86Weight.blue = blue;
- return 2;
- }
- else
- {
- ErrorF("Invalid weighting\n");
- return 0;
- }
- }
- if (!strcmp(argv[i], "-gamma") || !strcmp(argv[i], "-rgamma") ||
- !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma"))
- {
- double gamma;
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (sscanf(argv[++i], "%lf", &gamma) == 1) {
- if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) {
- ErrorF("gamma out of range, only %.2f <= gamma_value <= %.1f"
- " is valid\n", GAMMA_MIN, GAMMA_MAX);
- return 0;
- }
- if (!strcmp(argv[i-1], "-gamma"))
- xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma;
- else if (!strcmp(argv[i-1], "-rgamma")) xf86Gamma.red = gamma;
- else if (!strcmp(argv[i-1], "-ggamma")) xf86Gamma.green = gamma;
- else if (!strcmp(argv[i-1], "-bgamma")) xf86Gamma.blue = gamma;
- return 2;
- }
- }
- if (!strcmp(argv[i], "-layout"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- xf86LayoutName = argv[++i];
- return 2;
- }
- if (!strcmp(argv[i], "-screen"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- xf86ScreenName = argv[++i];
- return 2;
- }
- if (!strcmp(argv[i], "-pointer"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- xf86PointerName = argv[++i];
- return 2;
- }
- if (!strcmp(argv[i], "-keyboard"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- xf86KeyboardName = argv[++i];
- return 2;
- }
- if (!strcmp(argv[i], "-nosilk"))
- {
- xf86silkenMouseDisableFlag = TRUE;
- return 1;
- }
-#ifdef HAVE_ACPI
- if (!strcmp(argv[i], "-noacpi"))
- {
- xf86acpiDisableFlag = TRUE;
- return 1;
- }
-#endif
- if (!strcmp(argv[i], "-configure"))
- {
- if (getuid() != 0 && geteuid() == 0) {
- ErrorF("The '-configure' option can only be used by root.\n");
- exit(1);
- }
- xf86DoConfigure = TRUE;
- xf86AllowMouseOpenFail = TRUE;
- return 1;
- }
- if (!strcmp(argv[i], "-showopts"))
- {
- if (getuid() != 0 && geteuid() == 0) {
- ErrorF("The '-showopts' option can only be used by root.\n");
- exit(1);
- }
- xf86DoShowOptions = TRUE;
- return 1;
- }
- if (!strcmp(argv[i], "-isolateDevice"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (strncmp(argv[++i], "PCI:", 4)) {
- FatalError("Bus types other than PCI not yet isolable\n");
- }
- xf86PciIsolateDevice(argv[i]);
- return 2;
- }
- /* Notice cmdline xkbdir, but pass to dix as well */
- if (!strcmp(argv[i], "-xkbdir"))
- {
- xf86xkbdirFlag = TRUE;
- return 0;
- }
-
- /* OS-specific processing */
- return xf86ProcessArgument(argc, argv, i);
-}
-
-/*
- * ddxUseMsg --
- * Print out correct use of device dependent commandline options.
- * Maybe the user now knows what really to do ...
- */
-
-void
-ddxUseMsg(void)
-{
- ErrorF("\n");
- ErrorF("\n");
- ErrorF("Device Dependent Usage\n");
- if (getuid() == 0 || geteuid() != 0)
- {
- ErrorF("-modulepath paths specify the module search path\n");
- ErrorF("-logfile file specify a log file name\n");
- ErrorF("-configure probe for devices and write an "__XCONFIGFILE__"\n");
- ErrorF("-showopts print available options for all installed drivers\n");
- }
- ErrorF("-config file specify a configuration file, relative to the\n");
- ErrorF(" "__XCONFIGFILE__" search path, only root can use absolute\n");
- ErrorF("-configdir dir specify a configuration directory, relative to the\n");
- ErrorF(" "__XCONFIGDIR__" search path, only root can use absolute\n");
- ErrorF("-verbose [n] verbose startup messages\n");
- ErrorF("-logverbose [n] verbose log messages\n");
- ErrorF("-quiet minimal startup messages\n");
- ErrorF("-pixmap24 use 24bpp pixmaps for depth 24\n");
- ErrorF("-pixmap32 use 32bpp pixmaps for depth 24\n");
- ErrorF("-fbbpp n set bpp for the framebuffer. Default: 8\n");
- ErrorF("-depth n set colour depth. Default: 8\n");
- ErrorF("-gamma f set gamma value (0.1 < f < 10.0) Default: 1.0\n");
- ErrorF("-rgamma f set gamma value for red phase\n");
- ErrorF("-ggamma f set gamma value for green phase\n");
- ErrorF("-bgamma f set gamma value for blue phase\n");
- ErrorF("-weight nnn set RGB weighting at 16 bpp. Default: 565\n");
- ErrorF("-layout name specify the ServerLayout section name\n");
- ErrorF("-screen name specify the Screen section name\n");
- ErrorF("-keyboard name specify the core keyboard InputDevice name\n");
- ErrorF("-pointer name specify the core pointer InputDevice name\n");
- ErrorF("-nosilk disable Silken Mouse\n");
- ErrorF("-flipPixels swap default black/white Pixel values\n");
-#ifdef XF86VIDMODE
- ErrorF("-disableVidMode disable mode adjustments with xvidtune\n");
- ErrorF("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n");
-#endif
- ErrorF("-allowMouseOpenFail start server even if the mouse can't be initialized\n");
- ErrorF("-ignoreABI make module ABI mismatches non-fatal\n");
- ErrorF("-isolateDevice bus_id restrict device resets to bus_id (PCI only)\n");
- ErrorF("-version show the server version\n");
- ErrorF("-showDefaultModulePath show the server default module path\n");
- ErrorF("-showDefaultLibPath show the server default library path\n");
- /* OS-specific usage */
- xf86UseMsg();
- ErrorF("\n");
-}
-
-
-/*
- * xf86LoadModules iterates over a list that is being passed in.
- */
-Bool
-xf86LoadModules(char **list, pointer *optlist)
-{
- int errmaj, errmin;
- pointer opt;
- int i;
- char *name;
- Bool failed = FALSE;
-
- if (!list)
- return TRUE;
-
- for (i = 0; list[i] != NULL; i++) {
-
- /* Normalise the module name */
- name = xf86NormalizeName(list[i]);
-
- /* Skip empty names */
- if (name == NULL || *name == '\0') {
- free(name);
- continue;
- }
-
- /* Replace obsolete keyboard driver with kbd */
- if (!xf86NameCmp(name, "keyboard")) {
- strcpy(name, "kbd");
- }
-
- if (optlist)
- opt = optlist[i];
- else
- opt = NULL;
-
- if (!LoadModule(name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin)) {
- LoaderErrorMsg(NULL, name, errmaj, errmin);
- failed = TRUE;
- }
- free(name);
- }
- return !failed;
-}
-
-/* Pixmap format stuff */
-
-PixmapFormatPtr
-xf86GetPixFormat(ScrnInfoPtr pScrn, int depth)
-{
- int i;
- static PixmapFormatRec format; /* XXX not reentrant */
-
- /*
- * When the formats[] list initialisation isn't complete, check the
- * depth 24 pixmap config/cmdline options and screen-specified formats.
- */
-
- if (!formatsDone) {
- if (depth == 24) {
- Pix24Flags pix24 = Pix24DontCare;
-
- format.depth = 24;
- format.scanlinePad = BITMAP_SCANLINE_PAD;
- if (xf86Info.pixmap24 != Pix24DontCare)
- pix24 = xf86Info.pixmap24;
- else if (pScrn->pixmap24 != Pix24DontCare)
- pix24 = pScrn->pixmap24;
- if (pix24 == Pix24Use24)
- format.bitsPerPixel = 24;
- else
- format.bitsPerPixel = 32;
- return &format;
- }
- }
-
- for (i = 0; i < numFormats; i++)
- if (formats[i].depth == depth)
- break;
- if (i != numFormats)
- return &formats[i];
- else if (!formatsDone) {
- /* Check for screen-specified formats */
- for (i = 0; i < pScrn->numFormats; i++)
- if (pScrn->formats[i].depth == depth)
- break;
- if (i != pScrn->numFormats)
- return &pScrn->formats[i];
- }
- return NULL;
-}
-
-int
-xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth)
-{
- PixmapFormatPtr format;
-
-
- format = xf86GetPixFormat(pScrn, depth);
- if (format)
- return format->bitsPerPixel;
- else
- return 0;
-}
+/*
+ * Loosely based on code bearing the following copyright:
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ */
+/*
+ * Copyright (c) 1992-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).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+
+#undef HAS_UTSNAME
+#if !defined(WIN32)
+#define HAS_UTSNAME 1
+#include <sys/utsname.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include <X11/Xatom.h>
+#include "input.h"
+#include "servermd.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "site.h"
+#include "mi.h"
+
+#include "compiler.h"
+
+#include "loaderProcs.h"
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+#define XF86_OS_PRIVS
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Config.h"
+#include "xf86_OSlib.h"
+#include "xf86cmap.h"
+#include "xorgVersion.h"
+#include "xf86Build.h"
+#include "mipointer.h"
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include "xf86DDC.h"
+#include "xf86Xinput.h"
+#include "xf86InPriv.h"
+#include "picturestr.h"
+
+#include "xf86Bus.h"
+#include "xf86VGAarbiter.h"
+#include "globals.h"
+
+#ifdef DPMSExtension
+#include <X11/extensions/dpmsconst.h>
+#include "dpmsproc.h"
+#endif
+#include <hotplug.h>
+
+
+#ifdef XF86PM
+void (*xf86OSPMClose)(void) = NULL;
+#endif
+static Bool xorgHWOpenConsole = FALSE;
+
+/* Common pixmap formats */
+
+static PixmapFormatRec formats[MAXFORMATS] = {
+ { 1, 1, BITMAP_SCANLINE_PAD },
+ { 4, 8, BITMAP_SCANLINE_PAD },
+ { 8, 8, BITMAP_SCANLINE_PAD },
+ { 15, 16, BITMAP_SCANLINE_PAD },
+ { 16, 16, BITMAP_SCANLINE_PAD },
+ { 24, 32, BITMAP_SCANLINE_PAD },
+ { 32, 32, BITMAP_SCANLINE_PAD },
+};
+static int numFormats = 7;
+static Bool formatsDone = FALSE;
+
+#ifndef OSNAME
+#define OSNAME " unknown"
+#endif
+#ifndef OSVENDOR
+#define OSVENDOR ""
+#endif
+#ifndef PRE_RELEASE
+#define PRE_RELEASE XORG_VERSION_SNAP
+#endif
+
+static void
+xf86PrintBanner(void)
+{
+#if PRE_RELEASE
+ xf86ErrorFVerb(0, "\n"
+ "This is a pre-release version of the X server from " XVENDORNAME ".\n"
+ "It is not supported in any way.\n"
+ "Bugs may be filed in the bugzilla at http://bugs.freedesktop.org/.\n"
+ "Select the \"xorg\" product for bugs you find in this release.\n"
+ "Before reporting bugs in pre-release versions please check the\n"
+ "latest version in the X.Org Foundation git repository.\n"
+ "See http://wiki.x.org/wiki/GitPage for git access instructions.\n");
+#endif
+ xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d",
+ XORG_VERSION_MAJOR,
+ XORG_VERSION_MINOR,
+ XORG_VERSION_PATCH);
+#if XORG_VERSION_SNAP > 0
+ xf86ErrorFVerb(0, ".%d", XORG_VERSION_SNAP);
+#endif
+
+#if XORG_VERSION_SNAP >= 900
+ /* When the minor number is 99, that signifies that the we are making
+ * a release candidate for a major version. (X.0.0)
+ * When the patch number is 99, that signifies that the we are making
+ * a release candidate for a minor version. (X.Y.0)
+ * When the patch number is < 99, then we are making a release
+ * candidate for the next point release. (X.Y.Z)
+ */
+#if XORG_VERSION_MINOR >= 99
+ xf86ErrorFVerb(0, " (%d.0.0 RC %d)", XORG_VERSION_MAJOR+1,
+ XORG_VERSION_SNAP - 900);
+#elif XORG_VERSION_PATCH == 99
+ xf86ErrorFVerb(0, " (%d.%d.0 RC %d)", XORG_VERSION_MAJOR,
+ XORG_VERSION_MINOR + 1, XORG_VERSION_SNAP - 900);
+#else
+ xf86ErrorFVerb(0, " (%d.%d.%d RC %d)", XORG_VERSION_MAJOR,
+ XORG_VERSION_MINOR, XORG_VERSION_PATCH + 1,
+ XORG_VERSION_SNAP - 900);
+#endif
+#endif
+
+#ifdef XORG_CUSTOM_VERSION
+ xf86ErrorFVerb(0, " (%s)", XORG_CUSTOM_VERSION);
+#endif
+#ifndef XORG_DATE
+# define XORG_DATE "Unknown"
+#endif
+ xf86ErrorFVerb(0, "\nRelease Date: %s\n", XORG_DATE);
+ xf86ErrorFVerb(0, "X Protocol Version %d, Revision %d\n",
+ X_PROTOCOL, X_PROTOCOL_REVISION);
+ xf86ErrorFVerb(0, "Build Operating System: %s %s\n", OSNAME, OSVENDOR);
+#ifdef HAS_UTSNAME
+ {
+ struct utsname name;
+
+ /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX,
+ and Irix) and Single Unix Spec 3 just say that non-negative is success.
+ All agree that failure is represented by a negative number.
+ */
+ if (uname(&name) >= 0) {
+ xf86ErrorFVerb(0, "Current Operating System: %s %s %s %s %s\n",
+ name.sysname, name.nodename, name.release, name.version, name.machine);
+#ifdef linux
+ do {
+ char buf[80];
+ int fd = open("/proc/cmdline", O_RDONLY);
+ if (fd != -1) {
+ xf86ErrorFVerb(0, "Kernel command line: ");
+ memset(buf, 0, 80);
+ while (read(fd, buf, 80) > 0) {
+ xf86ErrorFVerb(0, "%.80s", buf);
+ memset(buf, 0, 80);
+ }
+ close(fd);
+ }
+ } while (0);
+#endif
+ }
+ }
+#endif
+#if defined(BUILD_DATE) && (BUILD_DATE > 19000000)
+ {
+ struct tm t;
+ char buf[100];
+
+ memset(&t, 0, sizeof(t));
+ memset(buf, 0, sizeof(buf));
+ t.tm_mday = BUILD_DATE % 100;
+ t.tm_mon = (BUILD_DATE / 100) % 100 - 1;
+ t.tm_year = BUILD_DATE / 10000 - 1900;
+#if defined(BUILD_TIME)
+ t.tm_sec = BUILD_TIME % 100;
+ t.tm_min = (BUILD_TIME / 100) % 100;
+ t.tm_hour = (BUILD_TIME / 10000) % 100;
+ if (strftime(buf, sizeof(buf), "%d %B %Y %I:%M:%S%p", &t))
+ xf86ErrorFVerb(0, "Build Date: %s\n", buf);
+#else
+ if (strftime(buf, sizeof(buf), "%d %B %Y", &t))
+ xf86ErrorFVerb(0, "Build Date: %s\n", buf);
+#endif
+ }
+#endif
+#if defined(BUILDERSTRING)
+ xf86ErrorFVerb(0, "%s \n", BUILDERSTRING);
+#endif
+ xf86ErrorFVerb(0, "Current version of pixman: %s\n",
+ pixman_version_string());
+ xf86ErrorFVerb(0, "\tBefore reporting problems, check "
+ ""__VENDORDWEBSUPPORT__"\n"
+ "\tto make sure that you have the latest version.\n");
+}
+
+static void
+xf86PrintMarkers(void)
+{
+ LogPrintMarkers();
+}
+
+static Bool
+xf86CreateRootWindow(WindowPtr pWin)
+{
+ int ret = TRUE;
+ int err = Success;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RootWinPropPtr pProp;
+ CreateWindowProcPtr CreateWindow = (CreateWindowProcPtr)
+ dixLookupPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey);
+
+ DebugF("xf86CreateRootWindow(%p)\n", pWin);
+
+ if ( pScreen->CreateWindow != xf86CreateRootWindow ) {
+ /* Can't find hook we are hung on */
+ xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */,
+ "xf86CreateRootWindow %p called when not in pScreen->CreateWindow %p n",
+ (void *)xf86CreateRootWindow,
+ (void *)pScreen->CreateWindow );
+ }
+
+ /* Unhook this function ... */
+ pScreen->CreateWindow = CreateWindow;
+ dixSetPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey, NULL);
+
+ /* ... and call the previous CreateWindow fuction, if any */
+ if (NULL!=pScreen->CreateWindow) {
+ ret = (*pScreen->CreateWindow)(pWin);
+ }
+
+ /* Now do our stuff */
+ if (xf86RegisteredPropertiesTable != NULL) {
+ if (pWin->parent == NULL && xf86RegisteredPropertiesTable != NULL) {
+ for (pProp = xf86RegisteredPropertiesTable[pScreen->myNum];
+ pProp != NULL && err==Success;
+ pProp = pProp->next )
+ {
+ Atom prop;
+
+ prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE);
+ err = dixChangeWindowProperty(serverClient, pWin,
+ prop, pProp->type,
+ pProp->format, PropModeReplace,
+ pProp->size, pProp->data,
+ FALSE);
+ }
+
+ /* Look at err */
+ ret &= (err==Success);
+
+ } else {
+ xf86Msg(X_ERROR, "xf86CreateRootWindow unexpectedly called with "
+ "non-root window %p (parent %p)\n",
+ (void *)pWin, (void *)pWin->parent);
+ ret = FALSE;
+ }
+ }
+
+ DebugF("xf86CreateRootWindow() returns %d\n", ret);
+ return ret;
+}
+
+
+static void
+InstallSignalHandlers(void)
+{
+ /*
+ * Install signal handler for unexpected signals
+ */
+ xf86Info.caughtSignal=FALSE;
+ if (!xf86Info.notrapSignals) {
+ OsRegisterSigWrapper(xf86SigWrapper);
+ } else {
+ signal(SIGSEGV, SIG_DFL);
+ signal(SIGILL, SIG_DFL);
+#ifdef SIGEMT
+ signal(SIGEMT, SIG_DFL);
+#endif
+ signal(SIGFPE, SIG_DFL);
+ signal(SIGBUS, SIG_DFL);
+ signal(SIGSYS, SIG_DFL);
+ signal(SIGXCPU, SIG_DFL);
+ signal(SIGXFSZ, SIG_DFL);
+ }
+}
+
+/*
+ * InitOutput --
+ * Initialize screenInfo for all actually accessible framebuffers.
+ * That includes vt-manager setup, querying all possible devices and
+ * collecting the pixmap formats.
+ */
+void
+InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ int i, j, k, scr_index, was_blocked = 0;
+ char **modulelist;
+ pointer *optionlist;
+ Pix24Flags screenpix24, pix24;
+ MessageType pix24From = X_DEFAULT;
+ Bool pix24Fail = FALSE;
+ Bool autoconfig = FALSE;
+ GDevPtr configured_device;
+
+ xf86Initialising = TRUE;
+
+ if (serverGeneration == 1) {
+ if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
+ xf86ServerName++;
+ else
+ xf86ServerName = argv[0];
+
+ xf86PrintBanner();
+ xf86PrintMarkers();
+ if (xf86LogFile) {
+ time_t t;
+ const char *ct;
+ t = time(NULL);
+ ct = ctime(&t);
+ xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
+ xf86LogFile, ct);
+ }
+
+ /* Read and parse the config file */
+ if (!xf86DoConfigure && !xf86DoShowOptions) {
+ switch (xf86HandleConfigFile(FALSE)) {
+ case CONFIG_OK:
+ break;
+ case CONFIG_PARSE_ERROR:
+ xf86Msg(X_ERROR, "Error parsing the config file\n");
+ return;
+ case CONFIG_NOFILE:
+ autoconfig = TRUE;
+ break;
+ }
+ }
+
+ InstallSignalHandlers();
+
+ /* Initialise the loader */
+ LoaderInit();
+
+ /* Tell the loader the default module search path */
+ LoaderSetPath(xf86ModulePath);
+
+ if (xf86Info.ignoreABI) {
+ LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
+ }
+
+ if (xf86DoShowOptions)
+ DoShowOptions();
+
+ /* Do a general bus probe. This will be a PCI probe for x86 platforms */
+ xf86BusProbe();
+
+ if (xf86DoConfigure)
+ DoConfigure();
+
+ if (autoconfig) {
+ if (!xf86AutoConfig()) {
+ xf86Msg(X_ERROR, "Auto configuration failed\n");
+ return;
+ }
+ }
+
+#ifdef XF86PM
+ xf86OSPMClose = xf86OSPMOpen();
+#endif
+
+ /* Load all modules specified explicitly in the config file */
+ if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
+ xf86LoadModules(modulelist, optionlist);
+ free(modulelist);
+ free(optionlist);
+ }
+
+ /* Load all driver modules specified in the config file */
+ /* If there aren't any specified in the config file, autoconfig them */
+ /* FIXME: Does not handle multiple active screen sections, but I'm not
+ * sure if we really want to handle that case*/
+ configured_device = xf86ConfigLayout.screens->screen->device;
+ if ((!configured_device) || (!configured_device->driver)) {
+ if (!autoConfigDevice(configured_device)) {
+ xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
+ return ;
+ }
+ }
+ if ((modulelist = xf86DriverlistFromConfig())) {
+ xf86LoadModules(modulelist, NULL);
+ free(modulelist);
+ }
+
+ /* Load all input driver modules specified in the config file. */
+ if ((modulelist = xf86InputDriverlistFromConfig())) {
+ xf86LoadModules(modulelist, NULL);
+ free(modulelist);
+ }
+
+ /*
+ * It is expected that xf86AddDriver()/xf86AddInputDriver will be
+ * called for each driver as it is loaded. Those functions save the
+ * module pointers for drivers.
+ * XXX Nothing keeps track of them for other modules.
+ */
+ /* XXX What do we do if not all of these could be loaded? */
+
+ /*
+ * At this point, xf86DriverList[] is all filled in with entries for
+ * each of the drivers to try and xf86NumDrivers has the number of
+ * drivers. If there are none, return now.
+ */
+
+ if (xf86NumDrivers == 0) {
+ xf86Msg(X_ERROR, "No drivers available.\n");
+ return;
+ }
+
+ /*
+ * Call each of the Identify functions and call the driverFunc to check
+ * if HW access is required. The Identify functions print out some
+ * identifying information, and anything else that might be
+ * needed at this early stage.
+ */
+
+ for (i = 0; i < xf86NumDrivers; i++) {
+ if (xf86DriverList[i]->Identify != NULL)
+ xf86DriverList[i]->Identify(0);
+
+ if (!xorgHWAccess || !xorgHWOpenConsole) {
+ xorgHWFlags flags;
+ if(!xf86DriverList[i]->driverFunc
+ || !xf86DriverList[i]->driverFunc(NULL,
+ GET_REQUIRED_HW_INTERFACES,
+ &flags))
+ flags = HW_IO;
+
+ if(NEED_IO_ENABLED(flags))
+ xorgHWAccess = TRUE;
+ if(!(flags & HW_SKIP_CONSOLE))
+ xorgHWOpenConsole = TRUE;
+ }
+ }
+
+ if (xorgHWOpenConsole)
+ xf86OpenConsole();
+ else
+ xf86Info.dontVTSwitch = TRUE;
+
+ if (xf86BusConfig() == FALSE)
+ return;
+
+ xf86PostProbe();
+
+ /*
+ * Sort the drivers to match the requested ording. Using a slow
+ * bubble sort.
+ */
+ for (j = 0; j < xf86NumScreens - 1; j++) {
+ for (i = 0; i < xf86NumScreens - j - 1; i++) {
+ if (xf86Screens[i + 1]->confScreen->screennum <
+ xf86Screens[i]->confScreen->screennum) {
+ ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
+ xf86Screens[i + 1] = xf86Screens[i];
+ xf86Screens[i] = tmpScrn;
+ }
+ }
+ }
+ /* Fix up the indexes */
+ for (i = 0; i < xf86NumScreens; i++) {
+ xf86Screens[i]->scrnIndex = i;
+ }
+
+ /*
+ * Call the driver's PreInit()'s to complete initialisation for the first
+ * generation.
+ */
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ xf86VGAarbiterScrnInit(xf86Screens[i]);
+ xf86VGAarbiterLock(xf86Screens[i]);
+ if (xf86Screens[i]->PreInit &&
+ xf86Screens[i]->PreInit(xf86Screens[i], 0))
+ xf86Screens[i]->configured = TRUE;
+ xf86VGAarbiterUnlock(xf86Screens[i]);
+ }
+ for (i = 0; i < xf86NumScreens; i++)
+ if (!xf86Screens[i]->configured)
+ xf86DeleteScreen(i--, 0);
+
+ /*
+ * If no screens left, return now.
+ */
+
+ if (xf86NumScreens == 0) {
+ xf86Msg(X_ERROR,
+ "Screen(s) found, but none have a usable configuration.\n");
+ return;
+ }
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ if (xf86Screens[i]->name == NULL) {
+ XNFasprintf(&xf86Screens[i]->name, "screen%d", i);
+ xf86MsgVerb(X_WARNING, 0,
+ "Screen driver %d has no name set, using `%s'.\n",
+ i, xf86Screens[i]->name);
+ }
+ }
+
+ /* Remove (unload) drivers that are not required */
+ for (i = 0; i < xf86NumDrivers; i++)
+ if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
+ xf86DeleteDriver(i);
+
+ /*
+ * At this stage we know how many screens there are.
+ */
+
+ for (i = 0; i < xf86NumScreens; i++)
+ xf86InitViewport(xf86Screens[i]);
+
+ /*
+ * Collect all pixmap formats and check for conflicts at the display
+ * level. Should we die here? Or just delete the offending screens?
+ */
+ screenpix24 = Pix24DontCare;
+ for (i = 0; i < xf86NumScreens; i++) {
+ if (xf86Screens[i]->imageByteOrder !=
+ xf86Screens[0]->imageByteOrder)
+ FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
+ if (xf86Screens[i]->bitmapScanlinePad !=
+ xf86Screens[0]->bitmapScanlinePad)
+ FatalError("Inconsistent display bitmapScanlinePad. Exiting\n");
+ if (xf86Screens[i]->bitmapScanlineUnit !=
+ xf86Screens[0]->bitmapScanlineUnit)
+ FatalError("Inconsistent display bitmapScanlineUnit. Exiting\n");
+ if (xf86Screens[i]->bitmapBitOrder !=
+ xf86Screens[0]->bitmapBitOrder)
+ FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
+
+ /* Determine the depth 24 pixmap format the screens would like */
+ if (xf86Screens[i]->pixmap24 != Pix24DontCare) {
+ if (screenpix24 == Pix24DontCare)
+ screenpix24 = xf86Screens[i]->pixmap24;
+ else if (screenpix24 != xf86Screens[i]->pixmap24)
+ FatalError("Inconsistent depth 24 pixmap format. Exiting\n");
+ }
+ }
+ /* check if screenpix24 is consistent with the config/cmdline */
+ if (xf86Info.pixmap24 != Pix24DontCare) {
+ pix24 = xf86Info.pixmap24;
+ pix24From = xf86Info.pix24From;
+ if (screenpix24 != Pix24DontCare && screenpix24 != xf86Info.pixmap24)
+ pix24Fail = TRUE;
+ } else if (screenpix24 != Pix24DontCare) {
+ pix24 = screenpix24;
+ pix24From = X_PROBED;
+ } else
+ pix24 = Pix24Use32;
+
+ if (pix24Fail)
+ FatalError("Screen(s) can't use the required depth 24 pixmap format"
+ " (%d). Exiting\n", PIX24TOBPP(pix24));
+
+ /* Initialise the depth 24 format */
+ for (j = 0; j < numFormats && formats[j].depth != 24; j++)
+ ;
+ formats[j].bitsPerPixel = PIX24TOBPP(pix24);
+
+ /* Collect additional formats */
+ for (i = 0; i < xf86NumScreens; i++) {
+ for (j = 0; j < xf86Screens[i]->numFormats; j++) {
+ for (k = 0; ; k++) {
+ if (k >= numFormats) {
+ if (k >= MAXFORMATS)
+ FatalError("Too many pixmap formats! Exiting\n");
+ formats[k] = xf86Screens[i]->formats[j];
+ numFormats++;
+ break;
+ }
+ if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
+ if ((formats[k].bitsPerPixel ==
+ xf86Screens[i]->formats[j].bitsPerPixel) &&
+ (formats[k].scanlinePad ==
+ xf86Screens[i]->formats[j].scanlinePad))
+ break;
+ FatalError("Inconsistent pixmap format for depth %d."
+ " Exiting\n", formats[k].depth);
+ }
+ }
+ }
+ }
+ formatsDone = TRUE;
+
+ if (xf86Info.vtno >= 0 ) {
+#define VT_ATOM_NAME "XFree86_VT"
+ Atom VTAtom=-1;
+ CARD32 *VT = NULL;
+ int ret;
+
+ /* This memory needs to stay available until the screen has been
+ initialized, and we can create the property for real.
+ */
+ if ( (VT = malloc(sizeof(CARD32)))==NULL ) {
+ FatalError("Unable to make VT property - out of memory. Exiting...\n");
+ }
+ *VT = xf86Info.vtno;
+
+ VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
+
+ for (i = 0, ret = Success; i < xf86NumScreens && ret == Success; i++) {
+ ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
+ VTAtom, XA_INTEGER, 32,
+ 1, VT );
+ if (ret != Success)
+ xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
+ "Failed to register VT 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) {
+ xf86Msg(pix24From, "Depth 24 pixmap format is %d bpp\n",
+ PIX24TOBPP(pix24));
+ break;
+ }
+ }
+ } else {
+ /*
+ * serverGeneration != 1; some OSs have to do things here, too.
+ */
+ if (xorgHWOpenConsole)
+ xf86OpenConsole();
+
+#ifdef XF86PM
+ /*
+ should we reopen it here? We need to deal with an already opened
+ device. We could leave this to the OS layer. For now we simply
+ close it here
+ */
+ if (xf86OSPMClose)
+ xf86OSPMClose();
+ if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
+ xf86MsgVerb(X_INFO, 3, "APM registered successfully\n");
+#endif
+
+ /* Make sure full I/O access is enabled */
+ if (xorgHWAccess)
+ xf86EnableIO();
+ }
+
+ /*
+ * Use the previously collected parts to setup pScreenInfo
+ */
+
+ pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
+ pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
+ pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
+ pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
+ pScreenInfo->numPixmapFormats = numFormats;
+ for (i = 0; i < numFormats; i++)
+ pScreenInfo->formats[i] = formats[i];
+
+ /* Make sure the server's VT is active */
+
+ if (serverGeneration != 1) {
+ xf86Resetting = TRUE;
+ /* All screens are in the same state, so just check the first */
+ if (!xf86Screens[0]->vtSema) {
+#ifdef HAS_USL_VTS
+ ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
+#endif
+ xf86AccessEnter();
+ was_blocked = xf86BlockSIGIO();
+ }
+ }
+
+ for (i = 0; i < xf86NumScreens; i++)
+ if (!xf86ColormapAllocatePrivates(xf86Screens[i]))
+ FatalError("Cannot register DDX private keys");
+
+ if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0) ||
+ !dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0))
+ FatalError("Cannot register DDX private keys");
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ xf86VGAarbiterLock(xf86Screens[i]);
+ /*
+ * Almost everything uses these defaults, and many of those that
+ * don't, will wrap them.
+ */
+ xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
+#ifdef XFreeXDGA
+ xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
+#endif
+ xf86Screens[i]->DPMSSet = NULL;
+ xf86Screens[i]->LoadPalette = NULL;
+ xf86Screens[i]->SetOverscan = NULL;
+ xf86Screens[i]->DriverFunc = NULL;
+ xf86Screens[i]->pScreen = NULL;
+ scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
+ xf86VGAarbiterUnlock(xf86Screens[i]);
+ if (scr_index == i) {
+ /*
+ * Hook in our ScrnInfoRec, and initialise some other pScreen
+ * fields.
+ */
+ dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
+ xf86ScreenKey, xf86Screens[i]);
+ xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
+ /* The driver should set this, but make sure it is set anyway */
+ xf86Screens[i]->vtSema = TRUE;
+ } else {
+ /* This shouldn't normally happen */
+ FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
+ }
+
+ DebugF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
+ i, xf86Screens[i]->pScreen );
+ DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
+ i, xf86Screens[i]->pScreen->CreateWindow );
+
+ dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
+ xf86CreateRootWindowKey,
+ xf86Screens[i]->pScreen->CreateWindow);
+ xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;
+
+ if (PictureGetSubpixelOrder (xf86Screens[i]->pScreen) == SubPixelUnknown)
+ {
+ xf86MonPtr DDC = (xf86MonPtr)(xf86Screens[i]->monitor->DDC);
+ PictureSetSubpixelOrder (xf86Screens[i]->pScreen,
+ DDC ?
+ (DDC->features.input_type ?
+ SubPixelHorizontalRGB : SubPixelNone) :
+ SubPixelUnknown);
+ }
+#ifdef RANDR
+ if (!xf86Info.disableRandR)
+ xf86RandRInit (screenInfo.screens[scr_index]);
+ xf86Msg(xf86Info.randRFrom, "RandR %s\n",
+ xf86Info.disableRandR ? "disabled" : "enabled");
+#endif
+ }
+
+ xf86VGAarbiterWrapFunctions();
+ xf86UnblockSIGIO(was_blocked);
+
+ xf86InitOrigins();
+
+ xf86Resetting = FALSE;
+ xf86Initialising = FALSE;
+
+ RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, xf86Wakeup,
+ NULL);
+}
+
+/*
+ * InitInput --
+ * Initialize all supported input devices.
+ */
+
+void
+InitInput(int argc, char **argv)
+{
+ InputInfoPtr* pDev;
+ DeviceIntPtr dev;
+
+ xf86Info.vtRequestsPending = FALSE;
+
+ mieqInit();
+
+ GetEventList(&xf86Events);
+
+ /* Initialize all configured input devices */
+ for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) {
+ /* Replace obsolete keyboard driver with kbd */
+ if (!xf86NameCmp((*pDev)->driver, "keyboard")) {
+ strcpy((*pDev)->driver, "kbd");
+ }
+
+ /* If one fails, the others will too */
+ if (xf86NewInputDevice(*pDev, &dev, TRUE) == BadAlloc)
+ break;
+ }
+
+ config_init();
+}
+
+void
+CloseInput (void)
+{
+ config_fini();
+}
+
+/*
+ * OsVendorInit --
+ * OS/Vendor-specific initialisations. Called from OsInit(), which
+ * is called by dix before establishing the well known sockets.
+ */
+
+void
+OsVendorInit(void)
+{
+ static Bool beenHere = FALSE;
+
+ signal(SIGCHLD, SIG_DFL); /* Need to wait for child processes */
+
+ if (!beenHere) {
+ umask(022);
+ xf86LogInit();
+ }
+
+ /* Set stderr to non-blocking. */
+#ifndef O_NONBLOCK
+#if defined(FNDELAY)
+#define O_NONBLOCK FNDELAY
+#elif defined(O_NDELAY)
+#define O_NONBLOCK O_NDELAY
+#endif
+
+#ifdef O_NONBLOCK
+ if (!beenHere) {
+ if (geteuid() == 0 && getuid() != geteuid())
+ {
+ int status;
+
+ status = fcntl(fileno(stderr), F_GETFL, 0);
+ if (status != -1) {
+ fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK);
+ }
+ }
+ }
+#endif
+#endif
+
+ beenHere = TRUE;
+}
+
+/*
+ * ddxGiveUp --
+ * Device dependent cleanup. Called by by dix before normal server death.
+ * For SYSV386 we must switch the terminal back to normal mode. No error-
+ * checking here, since there should be restored as much as possible.
+ */
+
+void
+ddxGiveUp(void)
+{
+ int i;
+
+ xf86VGAarbiterFini();
+
+#ifdef XF86PM
+ if (xf86OSPMClose)
+ xf86OSPMClose();
+ xf86OSPMClose = NULL;
+#endif
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ /*
+ * zero all access functions to
+ * trap calls when switched away.
+ */
+ xf86Screens[i]->vtSema = FALSE;
+ }
+
+#ifdef XFreeXDGA
+ DGAShutdown();
+#endif
+
+ if (xorgHWOpenConsole)
+ xf86CloseConsole();
+
+ xf86CloseLog();
+
+ /* If an unexpected signal was caught, dump a core for debugging */
+ if (xf86Info.caughtSignal)
+ OsAbort();
+}
+
+
+
+/*
+ * AbortDDX --
+ * DDX - specific abort routine. Called by AbortServer(). The attempt is
+ * made to restore all original setting of the displays. Also all devices
+ * are closed.
+ */
+
+void
+AbortDDX(void)
+{
+ int i;
+
+ xf86BlockSIGIO();
+
+ /*
+ * try to restore the original video state
+ */
+#ifdef DPMSExtension /* Turn screens back on */
+ if (DPMSPowerLevel != DPMSModeOn)
+ DPMSSet(serverClient, DPMSModeOn);
+#endif
+ if (xf86Screens) {
+ for (i = 0; i < xf86NumScreens; i++)
+ if (xf86Screens[i]->vtSema) {
+ /*
+ * if we are aborting before ScreenInit() has finished
+ * we might not have been wrapped yet. Therefore enable
+ * screen explicitely.
+ */
+ xf86VGAarbiterLock(xf86Screens[i]);
+ (xf86Screens[i]->LeaveVT)(i, 0);
+ xf86VGAarbiterUnlock(xf86Screens[i]);
+ }
+ }
+
+ xf86AccessLeave();
+
+ /*
+ * This is needed for an abnormal server exit, since the normal exit stuff
+ * MUST also be performed (i.e. the vt must be left in a defined state)
+ */
+ ddxGiveUp();
+}
+
+void
+OsVendorFatalError(void)
+{
+#ifdef VENDORSUPPORT
+ ErrorF("\nPlease refer to your Operating System Vendor support pages\n"
+ "at %s for support on this crash.\n",VENDORSUPPORT);
+#else
+ ErrorF("\nPlease consult the "XVENDORNAME" support \n"
+ "\t at "__VENDORDWEBSUPPORT__"\n for help. \n");
+#endif
+ if (xf86LogFile && xf86LogFileWasOpened)
+ ErrorF("Please also check the log file at \"%s\" for additional "
+ "information.\n", xf86LogFile);
+ ErrorF("\n");
+}
+
+int
+xf86SetVerbosity(int verb)
+{
+ int save = xf86Verbose;
+
+ xf86Verbose = verb;
+ LogSetParameter(XLOG_VERBOSITY, verb);
+ return save;
+}
+
+int
+xf86SetLogVerbosity(int verb)
+{
+ int save = xf86LogVerbose;
+
+ xf86LogVerbose = verb;
+ LogSetParameter(XLOG_FILE_VERBOSITY, verb);
+ return save;
+}
+
+static void
+xf86PrintDefaultModulePath(void)
+{
+ ErrorF("%s\n", DEFAULT_MODULE_PATH);
+}
+
+static void
+xf86PrintDefaultLibraryPath(void)
+{
+ ErrorF("%s\n", DEFAULT_LIBRARY_PATH);
+}
+
+/*
+ * ddxProcessArgument --
+ * Process device-dependent command line args. Returns 0 if argument is
+ * not device dependent, otherwise Count of number of elements of argv
+ * that are part of a device dependent commandline option.
+ *
+ */
+
+/* ARGSUSED */
+int
+ddxProcessArgument(int argc, char **argv, int i)
+{
+#define CHECK_FOR_REQUIRED_ARGUMENT() \
+ if (((i + 1) >= argc) || (!argv[i + 1])) { \
+ ErrorF("Required argument to %s not specified\n", argv[i]); \
+ UseMsg(); \
+ FatalError("Required argument to %s not specified\n", argv[i]); \
+ }
+
+ /* First the options that are only allowed for root */
+ if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) {
+ if ( (geteuid() == 0) && (getuid() != 0) ) {
+ FatalError("The '%s' option can only be used by root.\n", argv[i]);
+ }
+ else if (!strcmp(argv[i], "-modulepath"))
+ {
+ char *mp;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ mp = strdup(argv[i + 1]);
+ if (!mp)
+ FatalError("Can't allocate memory for ModulePath\n");
+ xf86ModulePath = mp;
+ xf86ModPathFrom = X_CMDLINE;
+ return 2;
+ }
+ else if (!strcmp(argv[i], "-logfile"))
+ {
+ char *lf;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ lf = strdup(argv[i + 1]);
+ if (!lf)
+ FatalError("Can't allocate memory for LogFile\n");
+ xf86LogFile = lf;
+ xf86LogFileFrom = X_CMDLINE;
+ return 2;
+ }
+ }
+ if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
+ FatalError("\nInvalid argument for %s\n"
+ "\tFor non-root users, the file specified with %s must be\n"
+ "\ta relative path and must not contain any \"..\" elements.\n"
+ "\tUsing default "__XCONFIGFILE__" search path.\n\n",
+ argv[i], argv[i]);
+ }
+ xf86ConfigFile = argv[i + 1];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-configdir"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
+ FatalError("\nInvalid argument for %s\n"
+ "\tFor non-root users, the file specified with %s must be\n"
+ "\ta relative path and must not contain any \"..\" elements.\n"
+ "\tUsing default "__XCONFIGDIR__" search path.\n\n",
+ argv[i], argv[i]);
+ }
+ xf86ConfigDir = argv[i + 1];
+ return 2;
+ }
+ if (!strcmp(argv[i],"-flipPixels"))
+ {
+ xf86FlipPixels = TRUE;
+ return 1;
+ }
+#ifdef XF86VIDMODE
+ if (!strcmp(argv[i],"-disableVidMode"))
+ {
+ xf86VidModeDisabled = TRUE;
+ return 1;
+ }
+ if (!strcmp(argv[i],"-allowNonLocalXvidtune"))
+ {
+ xf86VidModeAllowNonLocal = TRUE;
+ return 1;
+ }
+#endif
+ if (!strcmp(argv[i],"-allowMouseOpenFail"))
+ {
+ xf86AllowMouseOpenFail = TRUE;
+ return 1;
+ }
+ if (!strcmp(argv[i],"-ignoreABI"))
+ {
+ LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
+ return 1;
+ }
+ if (!strcmp(argv[i],"-verbose"))
+ {
+ if (++i < argc && argv[i])
+ {
+ char *end;
+ long val;
+ val = strtol(argv[i], &end, 0);
+ if (*end == '\0')
+ {
+ xf86SetVerbosity(val);
+ return 2;
+ }
+ }
+ xf86SetVerbosity(++xf86Verbose);
+ return 1;
+ }
+ if (!strcmp(argv[i],"-logverbose"))
+ {
+ if (++i < argc && argv[i])
+ {
+ char *end;
+ long val;
+ val = strtol(argv[i], &end, 0);
+ if (*end == '\0')
+ {
+ xf86SetLogVerbosity(val);
+ return 2;
+ }
+ }
+ xf86SetLogVerbosity(++xf86LogVerbose);
+ return 1;
+ }
+ if (!strcmp(argv[i],"-quiet"))
+ {
+ xf86SetVerbosity(-1);
+ return 1;
+ }
+ if (!strcmp(argv[i],"-showconfig") || !strcmp(argv[i],"-version"))
+ {
+ xf86PrintBanner();
+ exit(0);
+ }
+ if (!strcmp(argv[i],"-showDefaultModulePath"))
+ {
+ xf86PrintDefaultModulePath();
+ exit(0);
+ }
+ if (!strcmp(argv[i],"-showDefaultLibPath"))
+ {
+ xf86PrintDefaultLibraryPath();
+ exit(0);
+ }
+ /* Notice the -fp flag, but allow it to pass to the dix layer */
+ if (!strcmp(argv[i], "-fp"))
+ {
+ xf86fpFlag = TRUE;
+ return 0;
+ }
+ /* Notice the -bs flag, but allow it to pass to the dix layer */
+ if (!strcmp(argv[i], "-bs"))
+ {
+ xf86bsDisableFlag = TRUE;
+ return 0;
+ }
+ /* Notice the +bs flag, but allow it to pass to the dix layer */
+ if (!strcmp(argv[i], "+bs"))
+ {
+ xf86bsEnableFlag = TRUE;
+ return 0;
+ }
+ /* Notice the -s flag, but allow it to pass to the dix layer */
+ if (!strcmp(argv[i], "-s"))
+ {
+ xf86sFlag = TRUE;
+ return 0;
+ }
+ if (!strcmp(argv[i], "-pixmap24"))
+ {
+ xf86Pix24 = Pix24Use24;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-pixmap32"))
+ {
+ xf86Pix24 = Pix24Use32;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-fbbpp"))
+ {
+ int bpp;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (sscanf(argv[++i], "%d", &bpp) == 1)
+ {
+ xf86FbBpp = bpp;
+ return 2;
+ }
+ else
+ {
+ ErrorF("Invalid fbbpp\n");
+ return 0;
+ }
+ }
+ if (!strcmp(argv[i], "-depth"))
+ {
+ int depth;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (sscanf(argv[++i], "%d", &depth) == 1)
+ {
+ xf86Depth = depth;
+ return 2;
+ }
+ else
+ {
+ ErrorF("Invalid depth\n");
+ return 0;
+ }
+ }
+ if (!strcmp(argv[i], "-weight"))
+ {
+ int red, green, blue;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3)
+ {
+ xf86Weight.red = red;
+ xf86Weight.green = green;
+ xf86Weight.blue = blue;
+ return 2;
+ }
+ else
+ {
+ ErrorF("Invalid weighting\n");
+ return 0;
+ }
+ }
+ if (!strcmp(argv[i], "-gamma") || !strcmp(argv[i], "-rgamma") ||
+ !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma"))
+ {
+ double gamma;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (sscanf(argv[++i], "%lf", &gamma) == 1) {
+ if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) {
+ ErrorF("gamma out of range, only %.2f <= gamma_value <= %.1f"
+ " is valid\n", GAMMA_MIN, GAMMA_MAX);
+ return 0;
+ }
+ if (!strcmp(argv[i-1], "-gamma"))
+ xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma;
+ else if (!strcmp(argv[i-1], "-rgamma")) xf86Gamma.red = gamma;
+ else if (!strcmp(argv[i-1], "-ggamma")) xf86Gamma.green = gamma;
+ else if (!strcmp(argv[i-1], "-bgamma")) xf86Gamma.blue = gamma;
+ return 2;
+ }
+ }
+ if (!strcmp(argv[i], "-layout"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ xf86LayoutName = argv[++i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-screen"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ xf86ScreenName = argv[++i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-pointer"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ xf86PointerName = argv[++i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-keyboard"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ xf86KeyboardName = argv[++i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-nosilk"))
+ {
+ xf86silkenMouseDisableFlag = TRUE;
+ return 1;
+ }
+#ifdef HAVE_ACPI
+ if (!strcmp(argv[i], "-noacpi"))
+ {
+ xf86acpiDisableFlag = TRUE;
+ return 1;
+ }
+#endif
+ if (!strcmp(argv[i], "-configure"))
+ {
+ if (getuid() != 0 && geteuid() == 0) {
+ ErrorF("The '-configure' option can only be used by root.\n");
+ exit(1);
+ }
+ xf86DoConfigure = TRUE;
+ xf86AllowMouseOpenFail = TRUE;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-showopts"))
+ {
+ if (getuid() != 0 && geteuid() == 0) {
+ ErrorF("The '-showopts' option can only be used by root.\n");
+ exit(1);
+ }
+ xf86DoShowOptions = TRUE;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-isolateDevice"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (strncmp(argv[++i], "PCI:", 4)) {
+ FatalError("Bus types other than PCI not yet isolable\n");
+ }
+ xf86PciIsolateDevice(argv[i]);
+ return 2;
+ }
+ /* Notice cmdline xkbdir, but pass to dix as well */
+ if (!strcmp(argv[i], "-xkbdir"))
+ {
+ xf86xkbdirFlag = TRUE;
+ return 0;
+ }
+
+ /* OS-specific processing */
+ return xf86ProcessArgument(argc, argv, i);
+}
+
+/*
+ * ddxUseMsg --
+ * Print out correct use of device dependent commandline options.
+ * Maybe the user now knows what really to do ...
+ */
+
+void
+ddxUseMsg(void)
+{
+ ErrorF("\n");
+ ErrorF("\n");
+ ErrorF("Device Dependent Usage\n");
+ if (getuid() == 0 || geteuid() != 0)
+ {
+ ErrorF("-modulepath paths specify the module search path\n");
+ ErrorF("-logfile file specify a log file name\n");
+ ErrorF("-configure probe for devices and write an "__XCONFIGFILE__"\n");
+ ErrorF("-showopts print available options for all installed drivers\n");
+ }
+ ErrorF("-config file specify a configuration file, relative to the\n");
+ ErrorF(" "__XCONFIGFILE__" search path, only root can use absolute\n");
+ ErrorF("-configdir dir specify a configuration directory, relative to the\n");
+ ErrorF(" "__XCONFIGDIR__" search path, only root can use absolute\n");
+ ErrorF("-verbose [n] verbose startup messages\n");
+ ErrorF("-logverbose [n] verbose log messages\n");
+ ErrorF("-quiet minimal startup messages\n");
+ ErrorF("-pixmap24 use 24bpp pixmaps for depth 24\n");
+ ErrorF("-pixmap32 use 32bpp pixmaps for depth 24\n");
+ ErrorF("-fbbpp n set bpp for the framebuffer. Default: 8\n");
+ ErrorF("-depth n set colour depth. Default: 8\n");
+ ErrorF("-gamma f set gamma value (0.1 < f < 10.0) Default: 1.0\n");
+ ErrorF("-rgamma f set gamma value for red phase\n");
+ ErrorF("-ggamma f set gamma value for green phase\n");
+ ErrorF("-bgamma f set gamma value for blue phase\n");
+ ErrorF("-weight nnn set RGB weighting at 16 bpp. Default: 565\n");
+ ErrorF("-layout name specify the ServerLayout section name\n");
+ ErrorF("-screen name specify the Screen section name\n");
+ ErrorF("-keyboard name specify the core keyboard InputDevice name\n");
+ ErrorF("-pointer name specify the core pointer InputDevice name\n");
+ ErrorF("-nosilk disable Silken Mouse\n");
+ ErrorF("-flipPixels swap default black/white Pixel values\n");
+#ifdef XF86VIDMODE
+ ErrorF("-disableVidMode disable mode adjustments with xvidtune\n");
+ ErrorF("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n");
+#endif
+ ErrorF("-allowMouseOpenFail start server even if the mouse can't be initialized\n");
+ ErrorF("-ignoreABI make module ABI mismatches non-fatal\n");
+ ErrorF("-isolateDevice bus_id restrict device resets to bus_id (PCI only)\n");
+ ErrorF("-version show the server version\n");
+ ErrorF("-showDefaultModulePath show the server default module path\n");
+ ErrorF("-showDefaultLibPath show the server default library path\n");
+ /* OS-specific usage */
+ xf86UseMsg();
+ ErrorF("\n");
+}
+
+
+/*
+ * xf86LoadModules iterates over a list that is being passed in.
+ */
+Bool
+xf86LoadModules(char **list, pointer *optlist)
+{
+ int errmaj, errmin;
+ pointer opt;
+ int i;
+ char *name;
+ Bool failed = FALSE;
+
+ if (!list)
+ return TRUE;
+
+ for (i = 0; list[i] != NULL; i++) {
+
+ /* Normalise the module name */
+ name = xf86NormalizeName(list[i]);
+
+ /* Skip empty names */
+ if (name == NULL || *name == '\0') {
+ free(name);
+ continue;
+ }
+
+ /* Replace obsolete keyboard driver with kbd */
+ if (!xf86NameCmp(name, "keyboard")) {
+ strcpy(name, "kbd");
+ }
+
+ if (optlist)
+ opt = optlist[i];
+ else
+ opt = NULL;
+
+ if (!LoadModule(name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin)) {
+ LoaderErrorMsg(NULL, name, errmaj, errmin);
+ failed = TRUE;
+ }
+ free(name);
+ }
+ return !failed;
+}
+
+/* Pixmap format stuff */
+
+PixmapFormatPtr
+xf86GetPixFormat(ScrnInfoPtr pScrn, int depth)
+{
+ int i;
+ static PixmapFormatRec format; /* XXX not reentrant */
+
+ /*
+ * When the formats[] list initialisation isn't complete, check the
+ * depth 24 pixmap config/cmdline options and screen-specified formats.
+ */
+
+ if (!formatsDone) {
+ if (depth == 24) {
+ Pix24Flags pix24 = Pix24DontCare;
+
+ format.depth = 24;
+ format.scanlinePad = BITMAP_SCANLINE_PAD;
+ if (xf86Info.pixmap24 != Pix24DontCare)
+ pix24 = xf86Info.pixmap24;
+ else if (pScrn->pixmap24 != Pix24DontCare)
+ pix24 = pScrn->pixmap24;
+ if (pix24 == Pix24Use24)
+ format.bitsPerPixel = 24;
+ else
+ format.bitsPerPixel = 32;
+ return &format;
+ }
+ }
+
+ for (i = 0; i < numFormats; i++)
+ if (formats[i].depth == depth)
+ break;
+ if (i != numFormats)
+ return &formats[i];
+ else if (!formatsDone) {
+ /* Check for screen-specified formats */
+ for (i = 0; i < pScrn->numFormats; i++)
+ if (pScrn->formats[i].depth == depth)
+ break;
+ if (i != pScrn->numFormats)
+ return &pScrn->formats[i];
+ }
+ return NULL;
+}
+
+int
+xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth)
+{
+ PixmapFormatPtr format;
+
+
+ format = xf86GetPixFormat(pScrn, depth);
+ if (format)
+ return format->bitsPerPixel;
+ else
+ return 0;
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Module.h b/xorg-server/hw/xfree86/common/xf86Module.h
index 581047dcf..1322b8046 100644
--- a/xorg-server/hw/xfree86/common/xf86Module.h
+++ b/xorg-server/hw/xfree86/common/xf86Module.h
@@ -1,212 +1,212 @@
-/*
- * Copyright (c) 1997-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).
- */
-
-/*
- * This file contains the parts of the loader interface that are visible
- * to modules. This is the only loader-related header that modules should
- * include.
- *
- * It should include a bare minimum of other headers.
- *
- * Longer term, the module/loader code should probably live directly under
- * Xserver/.
- *
- * XXX This file arguably belongs in xfree86/loader/.
- */
-
-#ifndef _XF86MODULE_H
-#define _XF86MODULE_H
-
-#include "misc.h"
-#ifndef NULL
-#define NULL ((void *)0)
-#endif
-
-typedef enum {
- LD_RESOLV_IFDONE = 0, /* only check if no more
- delays pending */
- LD_RESOLV_NOW = 1, /* finish one delay step */
- LD_RESOLV_FORCE = 2 /* force checking... */
-} LoaderResolveOptions;
-
-#define DEFAULT_LIST ((char *)-1)
-
-/* This indicates a special module that doesn't have the usual entry point */
-#define EXTERN_MODULE ((pointer)-1)
-
-/* Built-in ABI classes. These definitions must not be changed. */
-#define ABI_CLASS_NONE NULL
-#define ABI_CLASS_ANSIC "X.Org ANSI C Emulation"
-#define ABI_CLASS_VIDEODRV "X.Org Video Driver"
-#define ABI_CLASS_XINPUT "X.Org XInput driver"
-#define ABI_CLASS_EXTENSION "X.Org Server Extension"
-#define ABI_CLASS_FONT "X.Org Font Renderer"
-
-#define ABI_MINOR_MASK 0x0000FFFF
-#define ABI_MAJOR_MASK 0xFFFF0000
-#define GET_ABI_MINOR(v) ((v) & ABI_MINOR_MASK)
-#define GET_ABI_MAJOR(v) (((v) & ABI_MAJOR_MASK) >> 16)
-#define SET_ABI_VERSION(maj, min) \
- ((((maj) << 16) & ABI_MAJOR_MASK) | ((min) & ABI_MINOR_MASK))
-
-/*
- * ABI versions. Each version has a major and minor revision. Modules
- * using lower minor revisions must work with servers of a higher minor
- * revision. There is no compatibility between different major revisions.
- * Whenever the ABI_ANSIC_VERSION is changed, the others must also be
- * changed. The minor revision mask is 0x0000FFFF and the major revision
- * mask is 0xFFFF0000.
- */
-#define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4)
-#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(10, 0)
-#define ABI_XINPUT_VERSION SET_ABI_VERSION(12, 2)
-#define ABI_EXTENSION_VERSION SET_ABI_VERSION(5, 0)
-#define ABI_FONT_VERSION SET_ABI_VERSION(0, 6)
-
-#define MODINFOSTRING1 0xef23fdc5
-#define MODINFOSTRING2 0x10dc023a
-
-#ifndef MODULEVENDORSTRING
-#define MODULEVENDORSTRING "X.Org Foundation"
-#endif
-
-/* Error return codes for errmaj. New codes must only be added at the end. */
-typedef enum {
- LDR_NOERROR = 0,
- LDR_NOMEM, /* memory allocation failed */
- LDR_NOENT, /* Module file does not exist */
- LDR_NOSUBENT, /* pre-requsite file to be sub-loaded does not exist */
- LDR_NOSPACE, /* internal module array full */
- LDR_NOMODOPEN, /* module file could not be opened (check errmin) */
- LDR_UNKTYPE, /* file is not a recognized module type */
- LDR_NOLOAD, /* type specific loader failed */
- LDR_ONCEONLY, /* Module should only be loaded once (not an error) */
- LDR_NOPORTOPEN, /* could not open port (check errmin) */
- LDR_NOHARDWARE, /* could not query/initialize the hardware device */
- LDR_MISMATCH, /* the module didn't match the spec'd requirments */
- LDR_BADUSAGE, /* LoadModule is called with bad arguments */
- LDR_INVALID, /* The module doesn't have a valid ModuleData object */
- LDR_BADOS, /* The module doesn't support the OS */
- LDR_MODSPECIFIC /* A module-specific error in the SetupProc */
-} LoaderErrorCode;
-
-/*
- * Some common module classes. The moduleclass can be used to identify
- * that modules loaded are of the correct type. This is a finer
- * classification than the ABI classes even though the default set of
- * classes have the same names. For example, not all modules that require
- * the video driver ABI are themselves video drivers.
- */
-#define MOD_CLASS_NONE NULL
-#define MOD_CLASS_VIDEODRV "X.Org Video Driver"
-#define MOD_CLASS_XINPUT "X.Org XInput Driver"
-#define MOD_CLASS_FONT "X.Org Font Renderer"
-#define MOD_CLASS_EXTENSION "X.Org Server Extension"
-
-/* This structure is expected to be returned by the initfunc */
-typedef struct {
- const char * modname; /* name of module, e.g. "foo" */
- const char * vendor; /* vendor specific string */
- CARD32 _modinfo1_; /* constant MODINFOSTRING1/2 to find */
- CARD32 _modinfo2_; /* infoarea with a binary editor or sign tool */
- CARD32 xf86version; /* contains XF86_VERSION_CURRENT */
- CARD8 majorversion; /* module-specific major version */
- CARD8 minorversion; /* module-specific minor version */
- CARD16 patchlevel; /* module-specific patch level */
- const char * abiclass; /* ABI class that the module uses */
- CARD32 abiversion; /* ABI version */
- const char * moduleclass; /* module class description */
- CARD32 checksum[4]; /* contains a digital signature of the */
- /* version info structure */
-} XF86ModuleVersionInfo;
-
-/*
- * This structure can be used to callers of LoadModule and LoadSubModule to
- * specify version and/or ABI requirements.
- */
-typedef struct {
- CARD8 majorversion; /* module-specific major version */
- CARD8 minorversion; /* moudle-specific minor version */
- CARD16 patchlevel; /* module-specific patch level */
- const char * abiclass; /* ABI class that the module uses */
- CARD32 abiversion; /* ABI version */
- const char * moduleclass; /* module class */
-} XF86ModReqInfo;
-
-/* values to indicate unspecified fields in XF86ModReqInfo. */
-#define MAJOR_UNSPEC 0xFF
-#define MINOR_UNSPEC 0xFF
-#define PATCH_UNSPEC 0xFFFF
-#define ABI_VERS_UNSPEC 0xFFFFFFFF
-
-#define MODULE_VERSION_NUMERIC(maj, min, patch) \
- ((((maj) & 0xFF) << 24) | (((min) & 0xFF) << 16) | (patch & 0xFFFF))
-#define GET_MODULE_MAJOR_VERSION(vers) (((vers) >> 24) & 0xFF)
-#define GET_MODULE_MINOR_VERSION(vers) (((vers) >> 16) & 0xFF)
-#define GET_MODULE_PATCHLEVEL(vers) ((vers) & 0xFFFF)
-
-#define INITARGS void
-
-typedef void (*InitExtension)(INITARGS);
-
-typedef struct {
- InitExtension initFunc;
- const char * name;
- Bool *disablePtr;
- InitExtension setupFunc;
- const char ** initDependencies;
-} ExtensionModule;
-
-extern _X_EXPORT ExtensionModule *ExtensionModuleList;
-
-/* Prototypes for Loader functions that are exported to modules */
-extern _X_EXPORT pointer LoadSubModule(pointer, const char *, const char **,
- const char **, pointer, const XF86ModReqInfo *,
- int *, int *);
-extern _X_EXPORT void UnloadSubModule(pointer);
-extern _X_EXPORT void UnloadModule (pointer);
-extern _X_EXPORT pointer LoaderSymbol(const char *);
-extern _X_EXPORT char **LoaderListDirs(const char **, const char **);
-extern _X_EXPORT void LoaderFreeDirList(char **);
-extern _X_EXPORT void LoaderErrorMsg(const char *, const char *, int, int);
-extern _X_EXPORT void LoadExtension(ExtensionModule *, Bool);
-extern _X_EXPORT void LoaderGetOS(const char **name, int *major, int *minor, int *teeny);
-extern _X_EXPORT Bool LoaderShouldIgnoreABI(void);
-extern _X_EXPORT int LoaderGetABIVersion(const char *abiclass);
-
-typedef pointer (*ModuleSetupProc)(pointer, pointer, int *, int *);
-typedef void (*ModuleTearDownProc)(pointer);
-#define MODULESETUPPROTO(func) pointer func(pointer, pointer, int*, int*)
-#define MODULETEARDOWNPROTO(func) void func(pointer)
-
-typedef struct {
- XF86ModuleVersionInfo * vers;
- ModuleSetupProc setup;
- ModuleTearDownProc teardown;
-} XF86ModuleData;
-
-#endif /* _XF86STR_H */
+/*
+ * Copyright (c) 1997-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).
+ */
+
+/*
+ * This file contains the parts of the loader interface that are visible
+ * to modules. This is the only loader-related header that modules should
+ * include.
+ *
+ * It should include a bare minimum of other headers.
+ *
+ * Longer term, the module/loader code should probably live directly under
+ * Xserver/.
+ *
+ * XXX This file arguably belongs in xfree86/loader/.
+ */
+
+#ifndef _XF86MODULE_H
+#define _XF86MODULE_H
+
+#include "misc.h"
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+typedef enum {
+ LD_RESOLV_IFDONE = 0, /* only check if no more
+ delays pending */
+ LD_RESOLV_NOW = 1, /* finish one delay step */
+ LD_RESOLV_FORCE = 2 /* force checking... */
+} LoaderResolveOptions;
+
+#define DEFAULT_LIST ((char *)-1)
+
+/* This indicates a special module that doesn't have the usual entry point */
+#define EXTERN_MODULE ((pointer)-1)
+
+/* Built-in ABI classes. These definitions must not be changed. */
+#define ABI_CLASS_NONE NULL
+#define ABI_CLASS_ANSIC "X.Org ANSI C Emulation"
+#define ABI_CLASS_VIDEODRV "X.Org Video Driver"
+#define ABI_CLASS_XINPUT "X.Org XInput driver"
+#define ABI_CLASS_EXTENSION "X.Org Server Extension"
+#define ABI_CLASS_FONT "X.Org Font Renderer"
+
+#define ABI_MINOR_MASK 0x0000FFFF
+#define ABI_MAJOR_MASK 0xFFFF0000
+#define GET_ABI_MINOR(v) ((v) & ABI_MINOR_MASK)
+#define GET_ABI_MAJOR(v) (((v) & ABI_MAJOR_MASK) >> 16)
+#define SET_ABI_VERSION(maj, min) \
+ ((((maj) << 16) & ABI_MAJOR_MASK) | ((min) & ABI_MINOR_MASK))
+
+/*
+ * ABI versions. Each version has a major and minor revision. Modules
+ * using lower minor revisions must work with servers of a higher minor
+ * revision. There is no compatibility between different major revisions.
+ * Whenever the ABI_ANSIC_VERSION is changed, the others must also be
+ * changed. The minor revision mask is 0x0000FFFF and the major revision
+ * mask is 0xFFFF0000.
+ */
+#define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4)
+#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(10, 0)
+#define ABI_XINPUT_VERSION SET_ABI_VERSION(12, 2)
+#define ABI_EXTENSION_VERSION SET_ABI_VERSION(5, 0)
+#define ABI_FONT_VERSION SET_ABI_VERSION(0, 6)
+
+#define MODINFOSTRING1 0xef23fdc5
+#define MODINFOSTRING2 0x10dc023a
+
+#ifndef MODULEVENDORSTRING
+#define MODULEVENDORSTRING "X.Org Foundation"
+#endif
+
+/* Error return codes for errmaj. New codes must only be added at the end. */
+typedef enum {
+ LDR_NOERROR = 0,
+ LDR_NOMEM, /* memory allocation failed */
+ LDR_NOENT, /* Module file does not exist */
+ LDR_NOSUBENT, /* pre-requsite file to be sub-loaded does not exist */
+ LDR_NOSPACE, /* internal module array full */
+ LDR_NOMODOPEN, /* module file could not be opened (check errmin) */
+ LDR_UNKTYPE, /* file is not a recognized module type */
+ LDR_NOLOAD, /* type specific loader failed */
+ LDR_ONCEONLY, /* Module should only be loaded once (not an error) */
+ LDR_NOPORTOPEN, /* could not open port (check errmin) */
+ LDR_NOHARDWARE, /* could not query/initialize the hardware device */
+ LDR_MISMATCH, /* the module didn't match the spec'd requirments */
+ LDR_BADUSAGE, /* LoadModule is called with bad arguments */
+ LDR_INVALID, /* The module doesn't have a valid ModuleData object */
+ LDR_BADOS, /* The module doesn't support the OS */
+ LDR_MODSPECIFIC /* A module-specific error in the SetupProc */
+} LoaderErrorCode;
+
+/*
+ * Some common module classes. The moduleclass can be used to identify
+ * that modules loaded are of the correct type. This is a finer
+ * classification than the ABI classes even though the default set of
+ * classes have the same names. For example, not all modules that require
+ * the video driver ABI are themselves video drivers.
+ */
+#define MOD_CLASS_NONE NULL
+#define MOD_CLASS_VIDEODRV "X.Org Video Driver"
+#define MOD_CLASS_XINPUT "X.Org XInput Driver"
+#define MOD_CLASS_FONT "X.Org Font Renderer"
+#define MOD_CLASS_EXTENSION "X.Org Server Extension"
+
+/* This structure is expected to be returned by the initfunc */
+typedef struct {
+ const char * modname; /* name of module, e.g. "foo" */
+ const char * vendor; /* vendor specific string */
+ CARD32 _modinfo1_; /* constant MODINFOSTRING1/2 to find */
+ CARD32 _modinfo2_; /* infoarea with a binary editor or sign tool */
+ CARD32 xf86version; /* contains XF86_VERSION_CURRENT */
+ CARD8 majorversion; /* module-specific major version */
+ CARD8 minorversion; /* module-specific minor version */
+ CARD16 patchlevel; /* module-specific patch level */
+ const char * abiclass; /* ABI class that the module uses */
+ CARD32 abiversion; /* ABI version */
+ const char * moduleclass; /* module class description */
+ CARD32 checksum[4]; /* contains a digital signature of the */
+ /* version info structure */
+} XF86ModuleVersionInfo;
+
+/*
+ * This structure can be used to callers of LoadModule and LoadSubModule to
+ * specify version and/or ABI requirements.
+ */
+typedef struct {
+ CARD8 majorversion; /* module-specific major version */
+ CARD8 minorversion; /* moudle-specific minor version */
+ CARD16 patchlevel; /* module-specific patch level */
+ const char * abiclass; /* ABI class that the module uses */
+ CARD32 abiversion; /* ABI version */
+ const char * moduleclass; /* module class */
+} XF86ModReqInfo;
+
+/* values to indicate unspecified fields in XF86ModReqInfo. */
+#define MAJOR_UNSPEC 0xFF
+#define MINOR_UNSPEC 0xFF
+#define PATCH_UNSPEC 0xFFFF
+#define ABI_VERS_UNSPEC 0xFFFFFFFF
+
+#define MODULE_VERSION_NUMERIC(maj, min, patch) \
+ ((((maj) & 0xFF) << 24) | (((min) & 0xFF) << 16) | (patch & 0xFFFF))
+#define GET_MODULE_MAJOR_VERSION(vers) (((vers) >> 24) & 0xFF)
+#define GET_MODULE_MINOR_VERSION(vers) (((vers) >> 16) & 0xFF)
+#define GET_MODULE_PATCHLEVEL(vers) ((vers) & 0xFFFF)
+
+#define INITARGS void
+
+typedef void (*InitExtension)(INITARGS);
+
+typedef struct {
+ InitExtension initFunc;
+ const char * name;
+ Bool *disablePtr;
+ InitExtension setupFunc;
+ const char ** initDependencies;
+} ExtensionModule;
+
+extern _X_EXPORT ExtensionModule *ExtensionModuleList;
+
+/* Prototypes for Loader functions that are exported to modules */
+extern _X_EXPORT pointer LoadSubModule(pointer, const char *, const char **,
+ const char **, pointer, const XF86ModReqInfo *,
+ int *, int *);
+extern _X_EXPORT void UnloadSubModule(pointer);
+extern _X_EXPORT void UnloadModule (pointer);
+extern _X_EXPORT pointer LoaderSymbol(const char *);
+extern _X_EXPORT char **LoaderListDirs(const char **, const char **);
+extern _X_EXPORT void LoaderFreeDirList(char **);
+extern _X_EXPORT void LoaderErrorMsg(const char *, const char *, int, int);
+extern _X_EXPORT void LoadExtension(ExtensionModule *, Bool);
+extern _X_EXPORT void LoaderGetOS(const char **name, int *major, int *minor, int *teeny);
+extern _X_EXPORT Bool LoaderShouldIgnoreABI(void);
+extern _X_EXPORT int LoaderGetABIVersion(const char *abiclass);
+
+typedef pointer (*ModuleSetupProc)(pointer, pointer, int *, int *);
+typedef void (*ModuleTearDownProc)(pointer);
+#define MODULESETUPPROTO(func) pointer func(pointer, pointer, int*, int*)
+#define MODULETEARDOWNPROTO(func) void func(pointer)
+
+typedef struct {
+ XF86ModuleVersionInfo * vers;
+ ModuleSetupProc setup;
+ ModuleTearDownProc teardown;
+} XF86ModuleData;
+
+#endif /* _XF86STR_H */
diff --git a/xorg-server/hw/xfree86/common/xf86Option.c b/xorg-server/hw/xfree86/common/xf86Option.c
index 480f38694..08f143347 100644
--- a/xorg-server/hw/xfree86/common/xf86Option.c
+++ b/xorg-server/hw/xfree86/common/xf86Option.c
@@ -1,916 +1,916 @@
-/*
- * 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).
- */
-
-/*
- * Author: David Dawes <dawes@xfree86.org>
- *
- * This file includes public option handling functions.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <X11/X.h>
-#include "os.h"
-#include "xf86.h"
-#include "xf86Xinput.h"
-#include "xf86Optrec.h"
-#include "xf86Parser.h"
-
-static Bool ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
- Bool markUsed);
-
-/*
- * xf86CollectOptions collects the options from each of the config file
- * sections used by the screen and puts the combined list in pScrn->options.
- * This function requires that the following have been initialised:
- *
- * pScrn->confScreen
- * pScrn->Entities[i]->device
- * pScrn->display
- * pScrn->monitor
- *
- * The extraOpts parameter may optionally contain a list of additional options
- * to include.
- *
- * The order of precedence for options is:
- *
- * extraOpts, display, confScreen, monitor, device
- */
-
-void
-xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts)
-{
- XF86OptionPtr tmp;
- XF86OptionPtr extras = (XF86OptionPtr)extraOpts;
- GDevPtr device;
-
- int i;
-
- pScrn->options = NULL;
-
- for (i=pScrn->numEntities - 1; i >= 0; i--) {
- device = xf86GetDevFromEntity(pScrn->entityList[i],
- pScrn->entityInstanceList[i]);
- if (device && device->options) {
- tmp = xf86optionListDup(device->options);
- if (pScrn->options)
- xf86optionListMerge(pScrn->options,tmp);
- else
- pScrn->options = tmp;
- }
- }
- if (pScrn->monitor->options) {
- tmp = xf86optionListDup(pScrn->monitor->options);
- if (pScrn->options)
- pScrn->options = xf86optionListMerge(pScrn->options, tmp);
- else
- pScrn->options = tmp;
- }
- if (pScrn->confScreen->options) {
- tmp = xf86optionListDup(pScrn->confScreen->options);
- if (pScrn->options)
- pScrn->options = xf86optionListMerge(pScrn->options, tmp);
- else
- pScrn->options = tmp;
- }
- if (pScrn->display->options) {
- tmp = xf86optionListDup(pScrn->display->options);
- if (pScrn->options)
- pScrn->options = xf86optionListMerge(pScrn->options, tmp);
- else
- pScrn->options = tmp;
- }
- if (extras) {
- tmp = xf86optionListDup(extras);
- if (pScrn->options)
- pScrn->options = xf86optionListMerge(pScrn->options, tmp);
- else
- pScrn->options = tmp;
- }
-}
-
-/*
- * xf86CollectInputOptions collects extra options for an InputDevice (other
- * than those added by the config backend).
- * The options are merged into the existing ones and thus take precedence
- * over the others.
- */
-
-void
-xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts)
-{
- if (defaultOpts) {
- XF86OptionPtr tmp =xf86optionListCreate(defaultOpts, -1, 0);
- if (pInfo->options)
- pInfo->options = xf86optionListMerge(tmp, pInfo->options);
- else
- pInfo->options = tmp;
- }
-}
-
-/**
- * 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)
-{
- pointer o = NULL;
-
- while (options)
- {
- o = xf86AddNewOption(o, xf86OptionName(options), xf86OptionValue(options));
- options = xf86nextOption(options);
- }
-
- return o;
-}
-
-
-/* Created for new XInput stuff -- essentially extensions to the parser */
-
-static int
-LookupIntOption(pointer optlist, const char *name, int deflt, Bool markUsed)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_INTEGER;
- if (ParseOptionValue(-1, optlist, &o, markUsed))
- deflt = o.value.num;
- return deflt;
-}
-
-
-static double
-LookupRealOption(pointer optlist, const char *name, double deflt,
- Bool markUsed)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_REAL;
- if (ParseOptionValue(-1, optlist, &o, markUsed))
- deflt = o.value.realnum;
- return deflt;
-}
-
-
-static char *
-LookupStrOption(pointer optlist, const char *name, char *deflt, Bool markUsed)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_STRING;
- if (ParseOptionValue(-1, optlist, &o, markUsed))
- deflt = o.value.str;
- if (deflt)
- return strdup(deflt);
- else
- return NULL;
-}
-
-
-static int
-LookupBoolOption(pointer optlist, const char *name, int deflt, Bool markUsed)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_BOOLEAN;
- if (ParseOptionValue(-1, optlist, &o, markUsed))
- deflt = o.value.bool;
- return deflt;
-}
-
-static double
-LookupPercentOption(pointer optlist, const char *name, double deflt, Bool markUsed)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_PERCENT;
- if (ParseOptionValue(-1, optlist, &o, markUsed))
- deflt = o.value.realnum;
- return deflt;
-}
-
-/* These xf86Set* functions are intended for use by non-screen specific code */
-
-int
-xf86SetIntOption(pointer optlist, const char *name, int deflt)
-{
- return LookupIntOption(optlist, name, deflt, TRUE);
-}
-
-
-double
-xf86SetRealOption(pointer optlist, const char *name, double deflt)
-{
- return LookupRealOption(optlist, name, deflt, TRUE);
-}
-
-
-char *
-xf86SetStrOption(pointer optlist, const char *name, char *deflt)
-{
- return LookupStrOption(optlist, name, deflt, TRUE);
-}
-
-
-int
-xf86SetBoolOption(pointer optlist, const char *name, int deflt)
-{
- return LookupBoolOption(optlist, name, deflt, TRUE);
-}
-
-double
-xf86SetPercentOption(pointer optlist, const char *name, double deflt)
-{
- return LookupPercentOption(optlist, name, deflt, TRUE);
-}
-
-/*
- * These are like the Set*Option functions, but they don't mark the options
- * as used.
- */
-int
-xf86CheckIntOption(pointer optlist, const char *name, int deflt)
-{
- return LookupIntOption(optlist, name, deflt, FALSE);
-}
-
-
-double
-xf86CheckRealOption(pointer optlist, const char *name, double deflt)
-{
- return LookupRealOption(optlist, name, deflt, FALSE);
-}
-
-
-char *
-xf86CheckStrOption(pointer optlist, const char *name, char *deflt)
-{
- return LookupStrOption(optlist, name, deflt, FALSE);
-}
-
-
-int
-xf86CheckBoolOption(pointer optlist, const char *name, int deflt)
-{
- return LookupBoolOption(optlist, name, deflt, FALSE);
-}
-
-
-double
-xf86CheckPercentOption(pointer optlist, const char *name, double deflt)
-{
- return LookupPercentOption(optlist, name, deflt, FALSE);
-}
-/*
- * 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)
-{
- char tmp[16];
- sprintf(tmp,"%i",val);
- return xf86AddNewOption(optlist,name,tmp);
-}
-
-pointer
-xf86ReplaceRealOption(pointer 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)
-{
- return xf86AddNewOption(optlist,name,val?"True":"False");
-}
-
-pointer
-xf86ReplacePercentOption(pointer 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)
-{
- return xf86AddNewOption(optlist,name,val);
-}
-
-pointer
-xf86AddNewOption(pointer head, const char *name, const char *val)
-{
- /* XXX These should actually be allocated in the parser library. */
- char *tmp = strdup(val);
- char *tmp_name = strdup(name);
-
- return xf86addNewOption(head, tmp_name, tmp);
-}
-
-
-pointer
-xf86NewOption(char *name, char *value)
-{
- return xf86newOption(name, value);
-}
-
-
-pointer
-xf86NextOption(pointer list)
-{
- return xf86nextOption(list);
-}
-
-pointer
-xf86OptionListCreate(const char **options, int count, int used)
-{
- return xf86optionListCreate(options, count, used);
-}
-
-pointer
-xf86OptionListMerge(pointer head, pointer tail)
-{
- return xf86optionListMerge(head, tail);
-}
-
-void
-xf86OptionListFree(pointer opt)
-{
- xf86optionListFree(opt);
-}
-
-char *
-xf86OptionName(pointer opt)
-{
- return xf86optionName(opt);
-}
-
-char *
-xf86OptionValue(pointer opt)
-{
- return xf86optionValue(opt);
-}
-
-void
-xf86OptionListReport(pointer parm)
-{
- XF86OptionPtr opts = parm;
-
- while(opts) {
- if (xf86optionValue(opts))
- xf86ErrorFVerb(5, "\tOption \"%s\" \"%s\"\n",
- xf86optionName(opts), xf86optionValue(opts));
- else
- xf86ErrorFVerb( 5, "\tOption \"%s\"\n", xf86optionName(opts));
- opts = xf86nextOption(opts);
- }
-}
-
-/* End of XInput-caused section */
-
-pointer
-xf86FindOption(pointer options, const char *name)
-{
- return xf86findOption(options, name);
-}
-
-
-char *
-xf86FindOptionValue(pointer options, const char *name)
-{
- return xf86findOptionValue(options, name);
-}
-
-
-void
-xf86MarkOptionUsed(pointer option)
-{
- if (option != NULL)
- ((XF86OptionPtr)option)->opt_used = TRUE;
-}
-
-
-void
-xf86MarkOptionUsedByName(pointer options, const char *name)
-{
- XF86OptionPtr opt;
-
- opt = xf86findOption(options, name);
- if (opt != NULL)
- opt->opt_used = TRUE;
-}
-
-Bool
-xf86CheckIfOptionUsed(pointer option)
-{
- if (option != NULL)
- return ((XF86OptionPtr)option)->opt_used;
- else
- return FALSE;
-}
-
-Bool
-xf86CheckIfOptionUsedByName(pointer options, const char *name)
-{
- XF86OptionPtr opt;
-
- opt = xf86findOption(options, name);
- if (opt != NULL)
- return opt->opt_used;
- else
- return FALSE;
-}
-
-void
-xf86ShowUnusedOptions(int scrnIndex, pointer options)
-{
- XF86OptionPtr opt = options;
-
- while (opt) {
- if (opt->opt_name && !opt->opt_used) {
- xf86DrvMsg(scrnIndex, X_WARNING, "Option \"%s\" is not used\n",
- opt->opt_name);
- }
- opt = opt->list.next;
- }
-}
-
-
-static Bool
-GetBoolValue(OptionInfoPtr p, const char *s)
-{
- return xf86getBoolValue(&p->value.bool, s);
-}
-
-static Bool
-ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
- Bool markUsed)
-{
- char *s, *end;
- Bool wasUsed = FALSE;
-
- if ((s = xf86findOptionValue(options, p->name)) != NULL) {
- if (markUsed) {
- wasUsed = xf86CheckIfOptionUsedByName(options, p->name);
- xf86MarkOptionUsedByName(options, p->name);
- }
- switch (p->type) {
- case OPTV_INTEGER:
- if (*s == '\0') {
- if (markUsed) {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires an integer value\n",
- p->name);
- }
- p->found = FALSE;
- } else {
- p->value.num = strtoul(s, &end, 0);
- if (*end == '\0') {
- p->found = TRUE;
- } else {
- if (markUsed) {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires an integer value\n",
- p->name);
- }
- p->found = FALSE;
- }
- }
- break;
- case OPTV_STRING:
- if (*s == '\0') {
- if (markUsed) {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires an string value\n",
- p->name);
- }
- p->found = FALSE;
- } else {
- p->value.str = s;
- p->found = TRUE;
- }
- break;
- case OPTV_ANYSTR:
- p->value.str = s;
- p->found = TRUE;
- break;
- case OPTV_REAL:
- if (*s == '\0') {
- if (markUsed) {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a floating point "
- "value\n", p->name);
- }
- p->found = FALSE;
- } else {
- p->value.realnum = strtod(s, &end);
- if (*end == '\0') {
- p->found = TRUE;
- } else {
- if (markUsed) {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a floating point "
- "value\n", p->name);
- }
- p->found = FALSE;
- }
- }
- break;
- case OPTV_BOOLEAN:
- if (GetBoolValue(p, s)) {
- p->found = TRUE;
- } else {
- if (markUsed) {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a boolean value\n",
- p->name);
- }
- p->found = FALSE;
- }
- break;
- case OPTV_PERCENT:
- {
- char tmp = 0;
- /* awkward match, but %% doesn't increase the match counter,
- * hence 100 looks the same as 100% to the caller of sccanf
- */
- if (sscanf(s, "%lf%c", &p->value.realnum, &tmp) != 2 || tmp != '%') {
- if (markUsed) {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a percent value\n", p->name);
- }
- p->found = FALSE;
- } else {
- p->found = TRUE;
- }
- }
- break;
- case OPTV_FREQ:
- if (*s == '\0') {
- if (markUsed) {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a frequency value\n",
- p->name);
- }
- p->found = FALSE;
- } else {
- double freq = strtod(s, &end);
- int units = 0;
-
- if (end != s) {
- p->found = TRUE;
- if (!xf86NameCmp(end, "Hz"))
- units = 1;
- else if (!xf86NameCmp(end, "kHz") ||
- !xf86NameCmp(end, "k"))
- units = 1000;
- else if (!xf86NameCmp(end, "MHz") ||
- !xf86NameCmp(end, "M"))
- units = 1000000;
- else {
- if (markUsed) {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a frequency value\n",
- p->name);
- }
- p->found = FALSE;
- }
- if (p->found)
- freq *= (double)units;
- } else {
- if (markUsed) {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a frequency value\n",
- p->name);
- }
- p->found = FALSE;
- }
- if (p->found) {
- p->value.freq.freq = freq;
- p->value.freq.units = units;
- }
- }
- break;
- case OPTV_NONE:
- /* Should never get here */
- p->found = FALSE;
- break;
- }
- if (p->found && markUsed) {
- int verb = 2;
- if (wasUsed)
- verb = 4;
- xf86DrvMsgVerb(scrnIndex, X_CONFIG, verb, "Option \"%s\"", p->name);
- if (!(p->type == OPTV_BOOLEAN && *s == 0)) {
- xf86ErrorFVerb(verb, " \"%s\"", s);
- }
- xf86ErrorFVerb(verb, "\n");
- }
- } else if (p->type == OPTV_BOOLEAN) {
- /* Look for matches with options with or without a "No" prefix. */
- char *n, *newn;
- OptionInfoRec opt;
-
- n = xf86NormalizeName(p->name);
- if (!n) {
- p->found = FALSE;
- return FALSE;
- }
- if (strncmp(n, "no", 2) == 0) {
- newn = n + 2;
- } else {
- free(n);
- if (asprintf(&n, "No%s", p->name) == -1) {
- p->found = FALSE;
- return FALSE;
- }
- newn = n;
- }
- if ((s = xf86findOptionValue(options, newn)) != NULL) {
- if (markUsed)
- xf86MarkOptionUsedByName(options, newn);
- if (GetBoolValue(&opt, s)) {
- p->value.bool = !opt.value.bool;
- p->found = TRUE;
- } else {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a boolean value\n", newn);
- p->found = FALSE;
- }
- } else {
- p->found = FALSE;
- }
- if (p->found && markUsed) {
- xf86DrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn);
- if (*s != 0) {
- xf86ErrorFVerb(2, " \"%s\"", s);
- }
- xf86ErrorFVerb(2, "\n");
- }
- free(n);
- } else {
- p->found = FALSE;
- }
- return p->found;
-}
-
-
-void
-xf86ProcessOptions(int scrnIndex, pointer options, OptionInfoPtr optinfo)
-{
- OptionInfoPtr p;
-
- for (p = optinfo; p->name != NULL; p++) {
- ParseOptionValue(scrnIndex, options, p, TRUE);
- }
-}
-
-
-OptionInfoPtr
-xf86TokenToOptinfo(const OptionInfoRec *table, int token)
-{
- const OptionInfoRec *p, *match = NULL, *set = NULL;
-
- if (!table) {
- ErrorF("xf86TokenToOptinfo: table is NULL\n");
- return NULL;
- }
-
- for (p = table; p->token >= 0; p++) {
- if (p->token == token) {
- match = p;
- if (p->found)
- set = p;
- }
- }
-
- if (set)
- return (OptionInfoPtr)set;
- else if (match)
- return (OptionInfoPtr)match;
- else
- return NULL;
-}
-
-
-const char *
-xf86TokenToOptName(const OptionInfoRec *table, int token)
-{
- const OptionInfoRec *p;
-
- p = xf86TokenToOptinfo(table, token);
- return p->name;
-}
-
-
-Bool
-xf86IsOptionSet(const OptionInfoRec *table, int token)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- return p && p->found;
-}
-
-
-char *
-xf86GetOptValString(const OptionInfoRec *table, int token)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found)
- return p->value.str;
- else
- return NULL;
-}
-
-
-Bool
-xf86GetOptValInteger(const OptionInfoRec *table, int token, int *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- *value = p->value.num;
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86GetOptValULong(const OptionInfoRec *table, int token, unsigned long *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- *value = p->value.num;
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86GetOptValReal(const OptionInfoRec *table, int token, double *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- *value = p->value.realnum;
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86GetOptValFreq(const OptionInfoRec *table, int token,
- OptFreqUnits expectedUnits, double *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- if (p->value.freq.units > 0) {
- /* Units give, so the scaling is known. */
- switch (expectedUnits) {
- case OPTUNITS_HZ:
- *value = p->value.freq.freq;
- break;
- case OPTUNITS_KHZ:
- *value = p->value.freq.freq / 1000.0;
- break;
- case OPTUNITS_MHZ:
- *value = p->value.freq.freq / 1000000.0;
- break;
- }
- } else {
- /* No units given, so try to guess the scaling. */
- switch (expectedUnits) {
- case OPTUNITS_HZ:
- *value = p->value.freq.freq;
- break;
- case OPTUNITS_KHZ:
- if (p->value.freq.freq > 1000.0)
- *value = p->value.freq.freq / 1000.0;
- else
- *value = p->value.freq.freq;
- break;
- case OPTUNITS_MHZ:
- if (p->value.freq.freq > 1000000.0)
- *value = p->value.freq.freq / 1000000.0;
- else if (p->value.freq.freq > 1000.0)
- *value = p->value.freq.freq / 1000.0;
- else
- *value = p->value.freq.freq;
- }
- }
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- *value = p->value.bool;
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- return p->value.bool;
- } else
- return def;
-}
-
-
-int
-xf86NameCmp(const char *s1, const char *s2)
-{
- return xf86nameCompare(s1, s2);
-}
-
-char *
-xf86NormalizeName(const char *s)
-{
- char *ret, *q;
- const char *p;
-
- if (s == NULL)
- return NULL;
-
- ret = malloc(strlen(s) + 1);
- for (p = s, q = ret; *p != 0; p++) {
- switch (*p) {
- case '_':
- case ' ':
- case '\t':
- continue;
- default:
- if (isupper(*p))
- *q++ = tolower(*p);
- else
- *q++ = *p;
- }
- }
- *q = '\0';
- return ret;
-}
+/*
+ * 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).
+ */
+
+/*
+ * Author: David Dawes <dawes@xfree86.org>
+ *
+ * This file includes public option handling functions.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <X11/X.h>
+#include "os.h"
+#include "xf86.h"
+#include "xf86Xinput.h"
+#include "xf86Optrec.h"
+#include "xf86Parser.h"
+
+static Bool ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
+ Bool markUsed);
+
+/*
+ * xf86CollectOptions collects the options from each of the config file
+ * sections used by the screen and puts the combined list in pScrn->options.
+ * This function requires that the following have been initialised:
+ *
+ * pScrn->confScreen
+ * pScrn->Entities[i]->device
+ * pScrn->display
+ * pScrn->monitor
+ *
+ * The extraOpts parameter may optionally contain a list of additional options
+ * to include.
+ *
+ * The order of precedence for options is:
+ *
+ * extraOpts, display, confScreen, monitor, device
+ */
+
+void
+xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts)
+{
+ XF86OptionPtr tmp;
+ XF86OptionPtr extras = (XF86OptionPtr)extraOpts;
+ GDevPtr device;
+
+ int i;
+
+ pScrn->options = NULL;
+
+ for (i=pScrn->numEntities - 1; i >= 0; i--) {
+ device = xf86GetDevFromEntity(pScrn->entityList[i],
+ pScrn->entityInstanceList[i]);
+ if (device && device->options) {
+ tmp = xf86optionListDup(device->options);
+ if (pScrn->options)
+ xf86optionListMerge(pScrn->options,tmp);
+ else
+ pScrn->options = tmp;
+ }
+ }
+ if (pScrn->monitor->options) {
+ tmp = xf86optionListDup(pScrn->monitor->options);
+ if (pScrn->options)
+ pScrn->options = xf86optionListMerge(pScrn->options, tmp);
+ else
+ pScrn->options = tmp;
+ }
+ if (pScrn->confScreen->options) {
+ tmp = xf86optionListDup(pScrn->confScreen->options);
+ if (pScrn->options)
+ pScrn->options = xf86optionListMerge(pScrn->options, tmp);
+ else
+ pScrn->options = tmp;
+ }
+ if (pScrn->display->options) {
+ tmp = xf86optionListDup(pScrn->display->options);
+ if (pScrn->options)
+ pScrn->options = xf86optionListMerge(pScrn->options, tmp);
+ else
+ pScrn->options = tmp;
+ }
+ if (extras) {
+ tmp = xf86optionListDup(extras);
+ if (pScrn->options)
+ pScrn->options = xf86optionListMerge(pScrn->options, tmp);
+ else
+ pScrn->options = tmp;
+ }
+}
+
+/*
+ * xf86CollectInputOptions collects extra options for an InputDevice (other
+ * than those added by the config backend).
+ * The options are merged into the existing ones and thus take precedence
+ * over the others.
+ */
+
+void
+xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts)
+{
+ if (defaultOpts) {
+ XF86OptionPtr tmp =xf86optionListCreate(defaultOpts, -1, 0);
+ if (pInfo->options)
+ pInfo->options = xf86optionListMerge(tmp, pInfo->options);
+ else
+ pInfo->options = tmp;
+ }
+}
+
+/**
+ * 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)
+{
+ pointer o = NULL;
+
+ while (options)
+ {
+ o = xf86AddNewOption(o, xf86OptionName(options), xf86OptionValue(options));
+ options = xf86nextOption(options);
+ }
+
+ return o;
+}
+
+
+/* Created for new XInput stuff -- essentially extensions to the parser */
+
+static int
+LookupIntOption(pointer optlist, const char *name, int deflt, Bool markUsed)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_INTEGER;
+ if (ParseOptionValue(-1, optlist, &o, markUsed))
+ deflt = o.value.num;
+ return deflt;
+}
+
+
+static double
+LookupRealOption(pointer optlist, const char *name, double deflt,
+ Bool markUsed)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_REAL;
+ if (ParseOptionValue(-1, optlist, &o, markUsed))
+ deflt = o.value.realnum;
+ return deflt;
+}
+
+
+static char *
+LookupStrOption(pointer optlist, const char *name, char *deflt, Bool markUsed)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_STRING;
+ if (ParseOptionValue(-1, optlist, &o, markUsed))
+ deflt = o.value.str;
+ if (deflt)
+ return strdup(deflt);
+ else
+ return NULL;
+}
+
+
+static int
+LookupBoolOption(pointer optlist, const char *name, int deflt, Bool markUsed)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_BOOLEAN;
+ if (ParseOptionValue(-1, optlist, &o, markUsed))
+ deflt = o.value.bool;
+ return deflt;
+}
+
+static double
+LookupPercentOption(pointer optlist, const char *name, double deflt, Bool markUsed)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_PERCENT;
+ if (ParseOptionValue(-1, optlist, &o, markUsed))
+ deflt = o.value.realnum;
+ return deflt;
+}
+
+/* These xf86Set* functions are intended for use by non-screen specific code */
+
+int
+xf86SetIntOption(pointer optlist, const char *name, int deflt)
+{
+ return LookupIntOption(optlist, name, deflt, TRUE);
+}
+
+
+double
+xf86SetRealOption(pointer optlist, const char *name, double deflt)
+{
+ return LookupRealOption(optlist, name, deflt, TRUE);
+}
+
+
+char *
+xf86SetStrOption(pointer optlist, const char *name, char *deflt)
+{
+ return LookupStrOption(optlist, name, deflt, TRUE);
+}
+
+
+int
+xf86SetBoolOption(pointer optlist, const char *name, int deflt)
+{
+ return LookupBoolOption(optlist, name, deflt, TRUE);
+}
+
+double
+xf86SetPercentOption(pointer optlist, const char *name, double deflt)
+{
+ return LookupPercentOption(optlist, name, deflt, TRUE);
+}
+
+/*
+ * These are like the Set*Option functions, but they don't mark the options
+ * as used.
+ */
+int
+xf86CheckIntOption(pointer optlist, const char *name, int deflt)
+{
+ return LookupIntOption(optlist, name, deflt, FALSE);
+}
+
+
+double
+xf86CheckRealOption(pointer optlist, const char *name, double deflt)
+{
+ return LookupRealOption(optlist, name, deflt, FALSE);
+}
+
+
+char *
+xf86CheckStrOption(pointer optlist, const char *name, char *deflt)
+{
+ return LookupStrOption(optlist, name, deflt, FALSE);
+}
+
+
+int
+xf86CheckBoolOption(pointer optlist, const char *name, int deflt)
+{
+ return LookupBoolOption(optlist, name, deflt, FALSE);
+}
+
+
+double
+xf86CheckPercentOption(pointer optlist, const char *name, double deflt)
+{
+ return LookupPercentOption(optlist, name, deflt, FALSE);
+}
+/*
+ * 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)
+{
+ char tmp[16];
+ sprintf(tmp,"%i",val);
+ return xf86AddNewOption(optlist,name,tmp);
+}
+
+pointer
+xf86ReplaceRealOption(pointer 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)
+{
+ return xf86AddNewOption(optlist,name,val?"True":"False");
+}
+
+pointer
+xf86ReplacePercentOption(pointer 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)
+{
+ return xf86AddNewOption(optlist,name,val);
+}
+
+pointer
+xf86AddNewOption(pointer head, const char *name, const char *val)
+{
+ /* XXX These should actually be allocated in the parser library. */
+ char *tmp = strdup(val);
+ char *tmp_name = strdup(name);
+
+ return xf86addNewOption(head, tmp_name, tmp);
+}
+
+
+pointer
+xf86NewOption(char *name, char *value)
+{
+ return xf86newOption(name, value);
+}
+
+
+pointer
+xf86NextOption(pointer list)
+{
+ return xf86nextOption(list);
+}
+
+pointer
+xf86OptionListCreate(const char **options, int count, int used)
+{
+ return xf86optionListCreate(options, count, used);
+}
+
+pointer
+xf86OptionListMerge(pointer head, pointer tail)
+{
+ return xf86optionListMerge(head, tail);
+}
+
+void
+xf86OptionListFree(pointer opt)
+{
+ xf86optionListFree(opt);
+}
+
+char *
+xf86OptionName(pointer opt)
+{
+ return xf86optionName(opt);
+}
+
+char *
+xf86OptionValue(pointer opt)
+{
+ return xf86optionValue(opt);
+}
+
+void
+xf86OptionListReport(pointer parm)
+{
+ XF86OptionPtr opts = parm;
+
+ while(opts) {
+ if (xf86optionValue(opts))
+ xf86ErrorFVerb(5, "\tOption \"%s\" \"%s\"\n",
+ xf86optionName(opts), xf86optionValue(opts));
+ else
+ xf86ErrorFVerb( 5, "\tOption \"%s\"\n", xf86optionName(opts));
+ opts = xf86nextOption(opts);
+ }
+}
+
+/* End of XInput-caused section */
+
+pointer
+xf86FindOption(pointer options, const char *name)
+{
+ return xf86findOption(options, name);
+}
+
+
+char *
+xf86FindOptionValue(pointer options, const char *name)
+{
+ return xf86findOptionValue(options, name);
+}
+
+
+void
+xf86MarkOptionUsed(pointer option)
+{
+ if (option != NULL)
+ ((XF86OptionPtr)option)->opt_used = TRUE;
+}
+
+
+void
+xf86MarkOptionUsedByName(pointer options, const char *name)
+{
+ XF86OptionPtr opt;
+
+ opt = xf86findOption(options, name);
+ if (opt != NULL)
+ opt->opt_used = TRUE;
+}
+
+Bool
+xf86CheckIfOptionUsed(pointer option)
+{
+ if (option != NULL)
+ return ((XF86OptionPtr)option)->opt_used;
+ else
+ return FALSE;
+}
+
+Bool
+xf86CheckIfOptionUsedByName(pointer options, const char *name)
+{
+ XF86OptionPtr opt;
+
+ opt = xf86findOption(options, name);
+ if (opt != NULL)
+ return opt->opt_used;
+ else
+ return FALSE;
+}
+
+void
+xf86ShowUnusedOptions(int scrnIndex, pointer options)
+{
+ XF86OptionPtr opt = options;
+
+ while (opt) {
+ if (opt->opt_name && !opt->opt_used) {
+ xf86DrvMsg(scrnIndex, X_WARNING, "Option \"%s\" is not used\n",
+ opt->opt_name);
+ }
+ opt = opt->list.next;
+ }
+}
+
+
+static Bool
+GetBoolValue(OptionInfoPtr p, const char *s)
+{
+ return xf86getBoolValue(&p->value.bool, s);
+}
+
+static Bool
+ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
+ Bool markUsed)
+{
+ char *s, *end;
+ Bool wasUsed = FALSE;
+
+ if ((s = xf86findOptionValue(options, p->name)) != NULL) {
+ if (markUsed) {
+ wasUsed = xf86CheckIfOptionUsedByName(options, p->name);
+ xf86MarkOptionUsedByName(options, p->name);
+ }
+ switch (p->type) {
+ case OPTV_INTEGER:
+ if (*s == '\0') {
+ if (markUsed) {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires an integer value\n",
+ p->name);
+ }
+ p->found = FALSE;
+ } else {
+ p->value.num = strtoul(s, &end, 0);
+ if (*end == '\0') {
+ p->found = TRUE;
+ } else {
+ if (markUsed) {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires an integer value\n",
+ p->name);
+ }
+ p->found = FALSE;
+ }
+ }
+ break;
+ case OPTV_STRING:
+ if (*s == '\0') {
+ if (markUsed) {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires an string value\n",
+ p->name);
+ }
+ p->found = FALSE;
+ } else {
+ p->value.str = s;
+ p->found = TRUE;
+ }
+ break;
+ case OPTV_ANYSTR:
+ p->value.str = s;
+ p->found = TRUE;
+ break;
+ case OPTV_REAL:
+ if (*s == '\0') {
+ if (markUsed) {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a floating point "
+ "value\n", p->name);
+ }
+ p->found = FALSE;
+ } else {
+ p->value.realnum = strtod(s, &end);
+ if (*end == '\0') {
+ p->found = TRUE;
+ } else {
+ if (markUsed) {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a floating point "
+ "value\n", p->name);
+ }
+ p->found = FALSE;
+ }
+ }
+ break;
+ case OPTV_BOOLEAN:
+ if (GetBoolValue(p, s)) {
+ p->found = TRUE;
+ } else {
+ if (markUsed) {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a boolean value\n",
+ p->name);
+ }
+ p->found = FALSE;
+ }
+ break;
+ case OPTV_PERCENT:
+ {
+ char tmp = 0;
+ /* awkward match, but %% doesn't increase the match counter,
+ * hence 100 looks the same as 100% to the caller of sccanf
+ */
+ if (sscanf(s, "%lf%c", &p->value.realnum, &tmp) != 2 || tmp != '%') {
+ if (markUsed) {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a percent value\n", p->name);
+ }
+ p->found = FALSE;
+ } else {
+ p->found = TRUE;
+ }
+ }
+ break;
+ case OPTV_FREQ:
+ if (*s == '\0') {
+ if (markUsed) {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a frequency value\n",
+ p->name);
+ }
+ p->found = FALSE;
+ } else {
+ double freq = strtod(s, &end);
+ int units = 0;
+
+ if (end != s) {
+ p->found = TRUE;
+ if (!xf86NameCmp(end, "Hz"))
+ units = 1;
+ else if (!xf86NameCmp(end, "kHz") ||
+ !xf86NameCmp(end, "k"))
+ units = 1000;
+ else if (!xf86NameCmp(end, "MHz") ||
+ !xf86NameCmp(end, "M"))
+ units = 1000000;
+ else {
+ if (markUsed) {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a frequency value\n",
+ p->name);
+ }
+ p->found = FALSE;
+ }
+ if (p->found)
+ freq *= (double)units;
+ } else {
+ if (markUsed) {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a frequency value\n",
+ p->name);
+ }
+ p->found = FALSE;
+ }
+ if (p->found) {
+ p->value.freq.freq = freq;
+ p->value.freq.units = units;
+ }
+ }
+ break;
+ case OPTV_NONE:
+ /* Should never get here */
+ p->found = FALSE;
+ break;
+ }
+ if (p->found && markUsed) {
+ int verb = 2;
+ if (wasUsed)
+ verb = 4;
+ xf86DrvMsgVerb(scrnIndex, X_CONFIG, verb, "Option \"%s\"", p->name);
+ if (!(p->type == OPTV_BOOLEAN && *s == 0)) {
+ xf86ErrorFVerb(verb, " \"%s\"", s);
+ }
+ xf86ErrorFVerb(verb, "\n");
+ }
+ } else if (p->type == OPTV_BOOLEAN) {
+ /* Look for matches with options with or without a "No" prefix. */
+ char *n, *newn;
+ OptionInfoRec opt;
+
+ n = xf86NormalizeName(p->name);
+ if (!n) {
+ p->found = FALSE;
+ return FALSE;
+ }
+ if (strncmp(n, "no", 2) == 0) {
+ newn = n + 2;
+ } else {
+ free(n);
+ if (asprintf(&n, "No%s", p->name) == -1) {
+ p->found = FALSE;
+ return FALSE;
+ }
+ newn = n;
+ }
+ if ((s = xf86findOptionValue(options, newn)) != NULL) {
+ if (markUsed)
+ xf86MarkOptionUsedByName(options, newn);
+ if (GetBoolValue(&opt, s)) {
+ p->value.bool = !opt.value.bool;
+ p->found = TRUE;
+ } else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a boolean value\n", newn);
+ p->found = FALSE;
+ }
+ } else {
+ p->found = FALSE;
+ }
+ if (p->found && markUsed) {
+ xf86DrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn);
+ if (*s != 0) {
+ xf86ErrorFVerb(2, " \"%s\"", s);
+ }
+ xf86ErrorFVerb(2, "\n");
+ }
+ free(n);
+ } else {
+ p->found = FALSE;
+ }
+ return p->found;
+}
+
+
+void
+xf86ProcessOptions(int scrnIndex, pointer options, OptionInfoPtr optinfo)
+{
+ OptionInfoPtr p;
+
+ for (p = optinfo; p->name != NULL; p++) {
+ ParseOptionValue(scrnIndex, options, p, TRUE);
+ }
+}
+
+
+OptionInfoPtr
+xf86TokenToOptinfo(const OptionInfoRec *table, int token)
+{
+ const OptionInfoRec *p, *match = NULL, *set = NULL;
+
+ if (!table) {
+ ErrorF("xf86TokenToOptinfo: table is NULL\n");
+ return NULL;
+ }
+
+ for (p = table; p->token >= 0; p++) {
+ if (p->token == token) {
+ match = p;
+ if (p->found)
+ set = p;
+ }
+ }
+
+ if (set)
+ return (OptionInfoPtr)set;
+ else if (match)
+ return (OptionInfoPtr)match;
+ else
+ return NULL;
+}
+
+
+const char *
+xf86TokenToOptName(const OptionInfoRec *table, int token)
+{
+ const OptionInfoRec *p;
+
+ p = xf86TokenToOptinfo(table, token);
+ return p->name;
+}
+
+
+Bool
+xf86IsOptionSet(const OptionInfoRec *table, int token)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ return p && p->found;
+}
+
+
+char *
+xf86GetOptValString(const OptionInfoRec *table, int token)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found)
+ return p->value.str;
+ else
+ return NULL;
+}
+
+
+Bool
+xf86GetOptValInteger(const OptionInfoRec *table, int token, int *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ *value = p->value.num;
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86GetOptValULong(const OptionInfoRec *table, int token, unsigned long *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ *value = p->value.num;
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86GetOptValReal(const OptionInfoRec *table, int token, double *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ *value = p->value.realnum;
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86GetOptValFreq(const OptionInfoRec *table, int token,
+ OptFreqUnits expectedUnits, double *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ if (p->value.freq.units > 0) {
+ /* Units give, so the scaling is known. */
+ switch (expectedUnits) {
+ case OPTUNITS_HZ:
+ *value = p->value.freq.freq;
+ break;
+ case OPTUNITS_KHZ:
+ *value = p->value.freq.freq / 1000.0;
+ break;
+ case OPTUNITS_MHZ:
+ *value = p->value.freq.freq / 1000000.0;
+ break;
+ }
+ } else {
+ /* No units given, so try to guess the scaling. */
+ switch (expectedUnits) {
+ case OPTUNITS_HZ:
+ *value = p->value.freq.freq;
+ break;
+ case OPTUNITS_KHZ:
+ if (p->value.freq.freq > 1000.0)
+ *value = p->value.freq.freq / 1000.0;
+ else
+ *value = p->value.freq.freq;
+ break;
+ case OPTUNITS_MHZ:
+ if (p->value.freq.freq > 1000000.0)
+ *value = p->value.freq.freq / 1000000.0;
+ else if (p->value.freq.freq > 1000.0)
+ *value = p->value.freq.freq / 1000.0;
+ else
+ *value = p->value.freq.freq;
+ }
+ }
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ *value = p->value.bool;
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ return p->value.bool;
+ } else
+ return def;
+}
+
+
+int
+xf86NameCmp(const char *s1, const char *s2)
+{
+ return xf86nameCompare(s1, s2);
+}
+
+char *
+xf86NormalizeName(const char *s)
+{
+ char *ret, *q;
+ const char *p;
+
+ if (s == NULL)
+ return NULL;
+
+ ret = malloc(strlen(s) + 1);
+ for (p = s, q = ret; *p != 0; p++) {
+ switch (*p) {
+ case '_':
+ case ' ':
+ case '\t':
+ continue;
+ default:
+ if (isupper(*p))
+ *q++ = tolower(*p);
+ else
+ *q++ = *p;
+ }
+ }
+ *q = '\0';
+ return ret;
+}
diff --git a/xorg-server/hw/xfree86/common/xf86RandR.c b/xorg-server/hw/xfree86/common/xf86RandR.c
index 4663d0366..e8e5a3696 100644
--- a/xorg-server/hw/xfree86/common/xf86RandR.c
+++ b/xorg-server/hw/xfree86/common/xf86RandR.c
@@ -1,485 +1,485 @@
-/*
- *
- * Copyright © 2002 Keith Packard, member of 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 name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD 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.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "os.h"
-#include "globals.h"
-#include "xf86.h"
-#include "xf86str.h"
-#include "xf86Priv.h"
-#include "xf86DDC.h"
-#include "mipointer.h"
-#include <randrstr.h>
-#include "inputstr.h"
-
-typedef struct _xf86RandRInfo {
- CreateScreenResourcesProcPtr CreateScreenResources;
- CloseScreenProcPtr CloseScreen;
- int virtualX;
- int virtualY;
- int mmWidth;
- int mmHeight;
- Rotation rotation;
-} XF86RandRInfoRec, *XF86RandRInfoPtr;
-
-static DevPrivateKeyRec xf86RandRKeyRec;
-static DevPrivateKey xf86RandRKey;
-
-#define XF86RANDRINFO(p) ((XF86RandRInfoPtr)dixLookupPrivate(&(p)->devPrivates, xf86RandRKey))
-
-static int
-xf86RandRModeRefresh (DisplayModePtr mode)
-{
- if (mode->VRefresh)
- return (int) (mode->VRefresh + 0.5);
- else if (mode->Clock == 0)
- return 0;
- else
- return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
-}
-
-static Bool
-xf86RandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
-{
- RRScreenSizePtr pSize;
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- DisplayModePtr mode;
- int refresh0 = 60;
- xorgRRModeMM RRModeMM;
-
- *rotations = RR_Rotate_0;
-
- for (mode = scrp->modes; mode != NULL ; mode = mode->next)
- {
- int refresh = xf86RandRModeRefresh (mode);
-
- if (mode == scrp->modes)
- refresh0 = refresh;
-
- RRModeMM.mode = mode;
- RRModeMM.virtX = randrp->virtualX;
- RRModeMM.virtY = randrp->virtualY;
- RRModeMM.mmWidth = randrp->mmWidth;
- RRModeMM.mmHeight = randrp->mmHeight;
-
- if(scrp->DriverFunc) {
- (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
- }
-
- pSize = RRRegisterSize (pScreen,
- mode->HDisplay, mode->VDisplay,
- RRModeMM.mmWidth, RRModeMM.mmHeight);
- if (!pSize)
- return FALSE;
- RRRegisterRate (pScreen, pSize, refresh);
- if (mode == scrp->currentMode &&
- mode->HDisplay == scrp->virtualX && mode->VDisplay == scrp->virtualY)
- RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
- if (mode->next == scrp->modes)
- break;
- }
- if (scrp->currentMode->HDisplay != randrp->virtualX ||
- scrp->currentMode->VDisplay != randrp->virtualY)
- {
- mode = scrp->modes;
-
- RRModeMM.mode = NULL;
- RRModeMM.virtX = randrp->virtualX;
- RRModeMM.virtY = randrp->virtualY;
- RRModeMM.mmWidth = randrp->mmWidth;
- RRModeMM.mmHeight = randrp->mmHeight;
-
- if(scrp->DriverFunc) {
- (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
- }
-
- pSize = RRRegisterSize (pScreen,
- randrp->virtualX, randrp->virtualY,
- RRModeMM.mmWidth, RRModeMM.mmHeight);
- if (!pSize)
- return FALSE;
- RRRegisterRate (pScreen, pSize, refresh0);
- if (scrp->virtualX == randrp->virtualX &&
- scrp->virtualY == randrp->virtualY)
- {
- RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
- }
- }
-
- /* If there is driver support for randr, let it set our supported rotations */
- if(scrp->DriverFunc) {
- xorgRRRotation RRRotation;
-
- RRRotation.RRRotations = *rotations;
- if (!(*scrp->DriverFunc)(scrp, RR_GET_INFO, &RRRotation))
- return TRUE;
- *rotations = RRRotation.RRRotations;
- }
-
- return TRUE;
-}
-
-static Bool
-xf86RandRSetMode (ScreenPtr pScreen,
- DisplayModePtr mode,
- Bool useVirtual,
- int mmWidth,
- int mmHeight)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- int oldWidth = pScreen->width;
- int oldHeight = pScreen->height;
- int oldmmWidth = pScreen->mmWidth;
- int oldmmHeight = pScreen->mmHeight;
- int oldVirtualX = scrp->virtualX;
- int oldVirtualY = scrp->virtualY;
- WindowPtr pRoot = pScreen->root;
- Bool ret = TRUE;
-
- if (pRoot && scrp->vtSema)
- (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
- if (useVirtual)
- {
- scrp->virtualX = randrp->virtualX;
- scrp->virtualY = randrp->virtualY;
- }
- else
- {
- scrp->virtualX = mode->HDisplay;
- scrp->virtualY = mode->VDisplay;
- }
-
- /*
- * The DIX forgets the physical dimensions we passed into RRRegisterSize, so
- * reconstruct them if possible.
- */
- if(scrp->DriverFunc) {
- xorgRRModeMM RRModeMM;
-
- RRModeMM.mode = mode;
- RRModeMM.virtX = scrp->virtualX;
- RRModeMM.virtY = scrp->virtualY;
- RRModeMM.mmWidth = mmWidth;
- RRModeMM.mmHeight = mmHeight;
-
- (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
-
- mmWidth = RRModeMM.mmWidth;
- mmHeight = RRModeMM.mmHeight;
- }
- if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
- {
- /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
- pScreen->width = scrp->virtualY;
- pScreen->height = scrp->virtualX;
- pScreen->mmWidth = mmHeight;
- pScreen->mmHeight = mmWidth;
- }
- else
- {
- pScreen->width = scrp->virtualX;
- pScreen->height = scrp->virtualY;
- pScreen->mmWidth = mmWidth;
- pScreen->mmHeight = mmHeight;
- }
- if (!xf86SwitchMode (pScreen, mode))
- {
- pScreen->width = oldWidth;
- pScreen->height = oldHeight;
- pScreen->mmWidth = oldmmWidth;
- pScreen->mmHeight = oldmmHeight;
- scrp->virtualX = oldVirtualX;
- scrp->virtualY = oldVirtualY;
- ret = FALSE;
- }
- /*
- * Make sure the layout is correct
- */
- xf86ReconfigureLayout();
-
- /*
- * Make sure the whole screen is visible
- */
- xf86SetViewport (pScreen, pScreen->width, pScreen->height);
- xf86SetViewport (pScreen, 0, 0);
- if (pRoot && scrp->vtSema)
- (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
- return ret;
-}
-
-static Bool
-xf86RandRSetConfig (ScreenPtr pScreen,
- Rotation rotation,
- int rate,
- RRScreenSizePtr pSize)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- DisplayModePtr mode;
- int pos[MAXDEVICES][2];
- Bool useVirtual = FALSE;
- Rotation oldRotation = randrp->rotation;
- DeviceIntPtr dev;
- Bool view_adjusted = FALSE;
-
- for (dev = inputInfo.devices; dev; dev = dev->next)
- {
- if (!IsMaster(dev) && !IsFloating(dev))
- continue;
-
- miPointerGetPosition(dev, &pos[dev->id][0], &pos[dev->id][1]);
- }
-
- for (mode = scrp->modes; ; mode = mode->next)
- {
- if (mode->HDisplay == pSize->width &&
- mode->VDisplay == pSize->height &&
- (rate == 0 || xf86RandRModeRefresh (mode) == rate))
- break;
- if (mode->next == scrp->modes)
- {
- if (pSize->width == randrp->virtualX &&
- pSize->height == randrp->virtualY)
- {
- mode = scrp->modes;
- useVirtual = TRUE;
- break;
- }
- return FALSE;
- }
- }
-
- if (randrp->rotation != rotation) {
-
- /* Have the driver do its thing. */
- if (scrp->DriverFunc) {
- xorgRRRotation RRRotation;
- RRRotation.RRConfig.rotation = rotation;
- RRRotation.RRConfig.rate = rate;
- RRRotation.RRConfig.width = pSize->width;
- RRRotation.RRConfig.height = pSize->height;
-
- /*
- * Currently we need to rely on HW support for rotation.
- */
- if (!(*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation))
- return FALSE;
- } else
- return FALSE;
-
- randrp->rotation = rotation;
- }
-
- if (!xf86RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight)) {
- if(randrp->rotation != oldRotation) {
- /* Have the driver undo its thing. */
- if (scrp->DriverFunc) {
- xorgRRRotation RRRotation;
- RRRotation.RRConfig.rotation = oldRotation;
- RRRotation.RRConfig.rate = xf86RandRModeRefresh (scrp->currentMode);
- RRRotation.RRConfig.width = scrp->virtualX;
- RRRotation.RRConfig.height = scrp->virtualY;
- (*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation);
- }
-
- randrp->rotation = oldRotation;
- }
- return FALSE;
- }
-
- /*
- * Move the cursor back where it belongs; SwitchMode repositions it
- * FIXME: duplicated code, see modes/xf86RandR12.c
- */
- for (dev = inputInfo.devices; dev; dev = dev->next)
- {
- if (!IsMaster(dev) && !IsFloating(dev))
- continue;
-
- if (pScreen == miPointerGetScreen(dev)) {
- int px = pos[dev->id][0];
- int py = pos[dev->id][1];
-
- px = (px >= pScreen->width ? (pScreen->width - 1) : px);
- py = (py >= pScreen->height ? (pScreen->height - 1) : py);
-
- /* Setting the viewpoint makes only sense on one device */
- if (!view_adjusted && IsMaster(dev)) {
- xf86SetViewport(pScreen, px, py);
- view_adjusted = TRUE;
- }
-
- (*pScreen->SetCursorPosition) (dev, pScreen, px, py, FALSE);
- }
- }
-
- return TRUE;
-}
-
-/*
- * Wait until the screen is initialized before whacking the
- * sizes around; otherwise the screen pixmap will be allocated
- * at the current mode size rather than the maximum size
- */
-static Bool
-xf86RandRCreateScreenResources (ScreenPtr pScreen)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-#if 0
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- DisplayModePtr mode;
-#endif
-
- pScreen->CreateScreenResources = randrp->CreateScreenResources;
- if (!(*pScreen->CreateScreenResources) (pScreen))
- return FALSE;
-
-#if 0
- mode = scrp->currentMode;
- if (mode)
- xf86RandRSetMode (pScreen, mode, TRUE);
-#endif
-
- return TRUE;
-}
-
-/*
- * Reset size back to original
- */
-static Bool
-xf86RandRCloseScreen (int index, ScreenPtr pScreen)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
- scrp->virtualX = pScreen->width = randrp->virtualX;
- scrp->virtualY = pScreen->height = randrp->virtualY;
- scrp->currentMode = scrp->modes;
- pScreen->CloseScreen = randrp->CloseScreen;
- free(randrp);
- dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, NULL);
- return (*pScreen->CloseScreen) (index, pScreen);
-}
-
-Rotation
-xf86GetRotation(ScreenPtr pScreen)
-{
- if (xf86RandRKey == NULL)
- return RR_Rotate_0;
-
- return XF86RANDRINFO(pScreen)->rotation;
-}
-
-/* Function to change RandR's idea of the virtual screen size */
-Bool
-xf86RandRSetNewVirtualAndDimensions(ScreenPtr pScreen,
- int newvirtX, int newvirtY, int newmmWidth, int newmmHeight,
- Bool resetMode)
-{
- XF86RandRInfoPtr randrp;
-
- if (xf86RandRKey == NULL)
- return FALSE;
-
- randrp = XF86RANDRINFO(pScreen);
- if (randrp == NULL)
- return FALSE;
-
- if (newvirtX > 0)
- randrp->virtualX = newvirtX;
-
- if (newvirtY > 0)
- randrp->virtualY = newvirtY;
-
- if (newmmWidth > 0)
- randrp->mmWidth = newmmWidth;
-
- if (newmmHeight > 0)
- randrp->mmHeight = newmmHeight;
-
- /* This is only for during server start */
- if (resetMode) {
- return (xf86RandRSetMode(pScreen,
- XF86SCRNINFO(pScreen)->currentMode,
- TRUE,
- pScreen->mmWidth, pScreen->mmHeight));
- }
-
- return TRUE;
-}
-
-Bool
-xf86RandRInit (ScreenPtr pScreen)
-{
- rrScrPrivPtr rp;
- XF86RandRInfoPtr randrp;
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
-
-#ifdef PANORAMIX
- /* XXX disable RandR when using Xinerama */
- if (!noPanoramiXExtension)
- return TRUE;
-#endif
-
- xf86RandRKey = &xf86RandRKeyRec;
-
- if (!dixRegisterPrivateKey(&xf86RandRKeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
-
- randrp = malloc(sizeof (XF86RandRInfoRec));
- if (!randrp)
- return FALSE;
-
- if (!RRScreenInit (pScreen))
- {
- free(randrp);
- return FALSE;
- }
- rp = rrGetScrPriv(pScreen);
- rp->rrGetInfo = xf86RandRGetInfo;
- rp->rrSetConfig = xf86RandRSetConfig;
-
- randrp->virtualX = scrp->virtualX;
- randrp->virtualY = scrp->virtualY;
- randrp->mmWidth = pScreen->mmWidth;
- randrp->mmHeight = pScreen->mmHeight;
-
- randrp->CreateScreenResources = pScreen->CreateScreenResources;
- pScreen->CreateScreenResources = xf86RandRCreateScreenResources;
-
- randrp->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xf86RandRCloseScreen;
-
- randrp->rotation = RR_Rotate_0;
-
- dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, randrp);
- return TRUE;
-}
-
-
+/*
+ *
+ * Copyright © 2002 Keith Packard, member of 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 name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include "os.h"
+#include "globals.h"
+#include "xf86.h"
+#include "xf86str.h"
+#include "xf86Priv.h"
+#include "xf86DDC.h"
+#include "mipointer.h"
+#include <randrstr.h>
+#include "inputstr.h"
+
+typedef struct _xf86RandRInfo {
+ CreateScreenResourcesProcPtr CreateScreenResources;
+ CloseScreenProcPtr CloseScreen;
+ int virtualX;
+ int virtualY;
+ int mmWidth;
+ int mmHeight;
+ Rotation rotation;
+} XF86RandRInfoRec, *XF86RandRInfoPtr;
+
+static DevPrivateKeyRec xf86RandRKeyRec;
+static DevPrivateKey xf86RandRKey;
+
+#define XF86RANDRINFO(p) ((XF86RandRInfoPtr)dixLookupPrivate(&(p)->devPrivates, xf86RandRKey))
+
+static int
+xf86RandRModeRefresh (DisplayModePtr mode)
+{
+ if (mode->VRefresh)
+ return (int) (mode->VRefresh + 0.5);
+ else if (mode->Clock == 0)
+ return 0;
+ else
+ return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
+}
+
+static Bool
+xf86RandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ RRScreenSizePtr pSize;
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ DisplayModePtr mode;
+ int refresh0 = 60;
+ xorgRRModeMM RRModeMM;
+
+ *rotations = RR_Rotate_0;
+
+ for (mode = scrp->modes; mode != NULL ; mode = mode->next)
+ {
+ int refresh = xf86RandRModeRefresh (mode);
+
+ if (mode == scrp->modes)
+ refresh0 = refresh;
+
+ RRModeMM.mode = mode;
+ RRModeMM.virtX = randrp->virtualX;
+ RRModeMM.virtY = randrp->virtualY;
+ RRModeMM.mmWidth = randrp->mmWidth;
+ RRModeMM.mmHeight = randrp->mmHeight;
+
+ if(scrp->DriverFunc) {
+ (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
+ }
+
+ pSize = RRRegisterSize (pScreen,
+ mode->HDisplay, mode->VDisplay,
+ RRModeMM.mmWidth, RRModeMM.mmHeight);
+ if (!pSize)
+ return FALSE;
+ RRRegisterRate (pScreen, pSize, refresh);
+ if (mode == scrp->currentMode &&
+ mode->HDisplay == scrp->virtualX && mode->VDisplay == scrp->virtualY)
+ RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
+ if (mode->next == scrp->modes)
+ break;
+ }
+ if (scrp->currentMode->HDisplay != randrp->virtualX ||
+ scrp->currentMode->VDisplay != randrp->virtualY)
+ {
+ mode = scrp->modes;
+
+ RRModeMM.mode = NULL;
+ RRModeMM.virtX = randrp->virtualX;
+ RRModeMM.virtY = randrp->virtualY;
+ RRModeMM.mmWidth = randrp->mmWidth;
+ RRModeMM.mmHeight = randrp->mmHeight;
+
+ if(scrp->DriverFunc) {
+ (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
+ }
+
+ pSize = RRRegisterSize (pScreen,
+ randrp->virtualX, randrp->virtualY,
+ RRModeMM.mmWidth, RRModeMM.mmHeight);
+ if (!pSize)
+ return FALSE;
+ RRRegisterRate (pScreen, pSize, refresh0);
+ if (scrp->virtualX == randrp->virtualX &&
+ scrp->virtualY == randrp->virtualY)
+ {
+ RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
+ }
+ }
+
+ /* If there is driver support for randr, let it set our supported rotations */
+ if(scrp->DriverFunc) {
+ xorgRRRotation RRRotation;
+
+ RRRotation.RRRotations = *rotations;
+ if (!(*scrp->DriverFunc)(scrp, RR_GET_INFO, &RRRotation))
+ return TRUE;
+ *rotations = RRRotation.RRRotations;
+ }
+
+ return TRUE;
+}
+
+static Bool
+xf86RandRSetMode (ScreenPtr pScreen,
+ DisplayModePtr mode,
+ Bool useVirtual,
+ int mmWidth,
+ int mmHeight)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ int oldWidth = pScreen->width;
+ int oldHeight = pScreen->height;
+ int oldmmWidth = pScreen->mmWidth;
+ int oldmmHeight = pScreen->mmHeight;
+ int oldVirtualX = scrp->virtualX;
+ int oldVirtualY = scrp->virtualY;
+ WindowPtr pRoot = pScreen->root;
+ Bool ret = TRUE;
+
+ if (pRoot && scrp->vtSema)
+ (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
+ if (useVirtual)
+ {
+ scrp->virtualX = randrp->virtualX;
+ scrp->virtualY = randrp->virtualY;
+ }
+ else
+ {
+ scrp->virtualX = mode->HDisplay;
+ scrp->virtualY = mode->VDisplay;
+ }
+
+ /*
+ * The DIX forgets the physical dimensions we passed into RRRegisterSize, so
+ * reconstruct them if possible.
+ */
+ if(scrp->DriverFunc) {
+ xorgRRModeMM RRModeMM;
+
+ RRModeMM.mode = mode;
+ RRModeMM.virtX = scrp->virtualX;
+ RRModeMM.virtY = scrp->virtualY;
+ RRModeMM.mmWidth = mmWidth;
+ RRModeMM.mmHeight = mmHeight;
+
+ (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
+
+ mmWidth = RRModeMM.mmWidth;
+ mmHeight = RRModeMM.mmHeight;
+ }
+ if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
+ {
+ /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
+ pScreen->width = scrp->virtualY;
+ pScreen->height = scrp->virtualX;
+ pScreen->mmWidth = mmHeight;
+ pScreen->mmHeight = mmWidth;
+ }
+ else
+ {
+ pScreen->width = scrp->virtualX;
+ pScreen->height = scrp->virtualY;
+ pScreen->mmWidth = mmWidth;
+ pScreen->mmHeight = mmHeight;
+ }
+ if (!xf86SwitchMode (pScreen, mode))
+ {
+ pScreen->width = oldWidth;
+ pScreen->height = oldHeight;
+ pScreen->mmWidth = oldmmWidth;
+ pScreen->mmHeight = oldmmHeight;
+ scrp->virtualX = oldVirtualX;
+ scrp->virtualY = oldVirtualY;
+ ret = FALSE;
+ }
+ /*
+ * Make sure the layout is correct
+ */
+ xf86ReconfigureLayout();
+
+ /*
+ * Make sure the whole screen is visible
+ */
+ xf86SetViewport (pScreen, pScreen->width, pScreen->height);
+ xf86SetViewport (pScreen, 0, 0);
+ if (pRoot && scrp->vtSema)
+ (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+ return ret;
+}
+
+static Bool
+xf86RandRSetConfig (ScreenPtr pScreen,
+ Rotation rotation,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ DisplayModePtr mode;
+ int pos[MAXDEVICES][2];
+ Bool useVirtual = FALSE;
+ Rotation oldRotation = randrp->rotation;
+ DeviceIntPtr dev;
+ Bool view_adjusted = FALSE;
+
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (!IsMaster(dev) && !IsFloating(dev))
+ continue;
+
+ miPointerGetPosition(dev, &pos[dev->id][0], &pos[dev->id][1]);
+ }
+
+ for (mode = scrp->modes; ; mode = mode->next)
+ {
+ if (mode->HDisplay == pSize->width &&
+ mode->VDisplay == pSize->height &&
+ (rate == 0 || xf86RandRModeRefresh (mode) == rate))
+ break;
+ if (mode->next == scrp->modes)
+ {
+ if (pSize->width == randrp->virtualX &&
+ pSize->height == randrp->virtualY)
+ {
+ mode = scrp->modes;
+ useVirtual = TRUE;
+ break;
+ }
+ return FALSE;
+ }
+ }
+
+ if (randrp->rotation != rotation) {
+
+ /* Have the driver do its thing. */
+ if (scrp->DriverFunc) {
+ xorgRRRotation RRRotation;
+ RRRotation.RRConfig.rotation = rotation;
+ RRRotation.RRConfig.rate = rate;
+ RRRotation.RRConfig.width = pSize->width;
+ RRRotation.RRConfig.height = pSize->height;
+
+ /*
+ * Currently we need to rely on HW support for rotation.
+ */
+ if (!(*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation))
+ return FALSE;
+ } else
+ return FALSE;
+
+ randrp->rotation = rotation;
+ }
+
+ if (!xf86RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight)) {
+ if(randrp->rotation != oldRotation) {
+ /* Have the driver undo its thing. */
+ if (scrp->DriverFunc) {
+ xorgRRRotation RRRotation;
+ RRRotation.RRConfig.rotation = oldRotation;
+ RRRotation.RRConfig.rate = xf86RandRModeRefresh (scrp->currentMode);
+ RRRotation.RRConfig.width = scrp->virtualX;
+ RRRotation.RRConfig.height = scrp->virtualY;
+ (*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation);
+ }
+
+ randrp->rotation = oldRotation;
+ }
+ return FALSE;
+ }
+
+ /*
+ * Move the cursor back where it belongs; SwitchMode repositions it
+ * FIXME: duplicated code, see modes/xf86RandR12.c
+ */
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (!IsMaster(dev) && !IsFloating(dev))
+ continue;
+
+ if (pScreen == miPointerGetScreen(dev)) {
+ int px = pos[dev->id][0];
+ int py = pos[dev->id][1];
+
+ px = (px >= pScreen->width ? (pScreen->width - 1) : px);
+ py = (py >= pScreen->height ? (pScreen->height - 1) : py);
+
+ /* Setting the viewpoint makes only sense on one device */
+ if (!view_adjusted && IsMaster(dev)) {
+ xf86SetViewport(pScreen, px, py);
+ view_adjusted = TRUE;
+ }
+
+ (*pScreen->SetCursorPosition) (dev, pScreen, px, py, FALSE);
+ }
+ }
+
+ return TRUE;
+}
+
+/*
+ * Wait until the screen is initialized before whacking the
+ * sizes around; otherwise the screen pixmap will be allocated
+ * at the current mode size rather than the maximum size
+ */
+static Bool
+xf86RandRCreateScreenResources (ScreenPtr pScreen)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+#if 0
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ DisplayModePtr mode;
+#endif
+
+ pScreen->CreateScreenResources = randrp->CreateScreenResources;
+ if (!(*pScreen->CreateScreenResources) (pScreen))
+ return FALSE;
+
+#if 0
+ mode = scrp->currentMode;
+ if (mode)
+ xf86RandRSetMode (pScreen, mode, TRUE);
+#endif
+
+ return TRUE;
+}
+
+/*
+ * Reset size back to original
+ */
+static Bool
+xf86RandRCloseScreen (int index, ScreenPtr pScreen)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+
+ scrp->virtualX = pScreen->width = randrp->virtualX;
+ scrp->virtualY = pScreen->height = randrp->virtualY;
+ scrp->currentMode = scrp->modes;
+ pScreen->CloseScreen = randrp->CloseScreen;
+ free(randrp);
+ dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, NULL);
+ return (*pScreen->CloseScreen) (index, pScreen);
+}
+
+Rotation
+xf86GetRotation(ScreenPtr pScreen)
+{
+ if (xf86RandRKey == NULL)
+ return RR_Rotate_0;
+
+ return XF86RANDRINFO(pScreen)->rotation;
+}
+
+/* Function to change RandR's idea of the virtual screen size */
+Bool
+xf86RandRSetNewVirtualAndDimensions(ScreenPtr pScreen,
+ int newvirtX, int newvirtY, int newmmWidth, int newmmHeight,
+ Bool resetMode)
+{
+ XF86RandRInfoPtr randrp;
+
+ if (xf86RandRKey == NULL)
+ return FALSE;
+
+ randrp = XF86RANDRINFO(pScreen);
+ if (randrp == NULL)
+ return FALSE;
+
+ if (newvirtX > 0)
+ randrp->virtualX = newvirtX;
+
+ if (newvirtY > 0)
+ randrp->virtualY = newvirtY;
+
+ if (newmmWidth > 0)
+ randrp->mmWidth = newmmWidth;
+
+ if (newmmHeight > 0)
+ randrp->mmHeight = newmmHeight;
+
+ /* This is only for during server start */
+ if (resetMode) {
+ return (xf86RandRSetMode(pScreen,
+ XF86SCRNINFO(pScreen)->currentMode,
+ TRUE,
+ pScreen->mmWidth, pScreen->mmHeight));
+ }
+
+ return TRUE;
+}
+
+Bool
+xf86RandRInit (ScreenPtr pScreen)
+{
+ rrScrPrivPtr rp;
+ XF86RandRInfoPtr randrp;
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+
+#ifdef PANORAMIX
+ /* XXX disable RandR when using Xinerama */
+ if (!noPanoramiXExtension)
+ return TRUE;
+#endif
+
+ xf86RandRKey = &xf86RandRKeyRec;
+
+ if (!dixRegisterPrivateKey(&xf86RandRKeyRec, PRIVATE_SCREEN, 0))
+ return FALSE;
+
+ randrp = malloc(sizeof (XF86RandRInfoRec));
+ if (!randrp)
+ return FALSE;
+
+ if (!RRScreenInit (pScreen))
+ {
+ free(randrp);
+ return FALSE;
+ }
+ rp = rrGetScrPriv(pScreen);
+ rp->rrGetInfo = xf86RandRGetInfo;
+ rp->rrSetConfig = xf86RandRSetConfig;
+
+ randrp->virtualX = scrp->virtualX;
+ randrp->virtualY = scrp->virtualY;
+ randrp->mmWidth = pScreen->mmWidth;
+ randrp->mmHeight = pScreen->mmHeight;
+
+ randrp->CreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = xf86RandRCreateScreenResources;
+
+ randrp->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xf86RandRCloseScreen;
+
+ randrp->rotation = RR_Rotate_0;
+
+ dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, randrp);
+ return TRUE;
+}
+
+
diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c
index ef4542c5f..8356f79f8 100644
--- a/xorg-server/hw/xfree86/common/xf86Xinput.c
+++ b/xorg-server/hw/xfree86/common/xf86Xinput.c
@@ -1,1402 +1,1402 @@
-/*
- * 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,
- * 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).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/Xfuncproto.h>
-#include <X11/Xmd.h>
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include <X11/Xatom.h>
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86Config.h"
-#include "xf86Xinput.h"
-#include "xf86Optrec.h"
-#include "mipointer.h"
-#include "extinit.h"
-#include "loaderProcs.h"
-
-#include "exevents.h" /* AddInputDevice */
-#include "exglobals.h"
-#include "eventstr.h"
-#include "inpututils.h"
-
-#include <string.h> /* InputClassMatches */
-#ifdef HAVE_FNMATCH_H
-#include <fnmatch.h>
-#endif
-#ifdef HAVE_SYS_UTSNAME_H
-#include <sys/utsname.h>
-#endif
-
-#include <stdarg.h>
-#include <stdint.h> /* for int64_t */
-
-#include "mi.h"
-
-#include <ptrveloc.h> /* dix pointer acceleration */
-#include <xserver-properties.h>
-
-#ifdef XFreeXDGA
-#include "dgaproc.h"
-#endif
-
-#include "xkbsrv.h"
-
-/* Valuator verification macro */
-#define XI_VERIFY_VALUATORS(num_valuators) \
- if (num_valuators > MAX_VALUATORS) { \
- xf86Msg(X_ERROR, "%s: num_valuator %d is greater than" \
- " MAX_VALUATORS\n", __FUNCTION__, num_valuators); \
- return; \
- }
-
-EventListPtr xf86Events = NULL;
-
-static int
-xf86InputDevicePostInit(DeviceIntPtr dev);
-
-/**
- * Eval config and modify DeviceVelocityRec accordingly
- */
-static void
-ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list,
- DeviceVelocityPtr s)
-{
- int tempi;
- float tempf;
- Atom float_prop = XIGetKnownProperty(XATOM_FLOAT);
- Atom prop;
-
- if(!s)
- return;
-
- /* common settings (available via device properties) */
- tempf = xf86SetRealOption(list, "ConstantDeceleration", 1.0);
- if (tempf > 1.0) {
- xf86Msg(X_CONFIG, "%s: (accel) constant deceleration by %.1f\n",
- devname, tempf);
- prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
- XIChangeDeviceProperty(pDev, prop, float_prop, 32,
- PropModeReplace, 1, &tempf, FALSE);
- }
-
- tempf = xf86SetRealOption(list, "AdaptiveDeceleration", 1.0);
- if (tempf > 1.0) {
- xf86Msg(X_CONFIG, "%s: (accel) adaptive deceleration by %.1f\n",
- devname, tempf);
- prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
- XIChangeDeviceProperty(pDev, prop, float_prop, 32,
- PropModeReplace, 1, &tempf, FALSE);
- }
-
- /* select profile by number */
- tempi = xf86SetIntOption(list, "AccelerationProfile",
- s->statistics.profile_number);
-
- prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
- if (XIChangeDeviceProperty(pDev, prop, XA_INTEGER, 32,
- PropModeReplace, 1, &tempi, FALSE) == Success) {
- xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i\n", devname,
- tempi);
- } else {
- xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i is unknown\n",
- devname, tempi);
- }
-
- /* set scaling */
- tempf = xf86SetRealOption(list, "ExpectedRate", 0);
- prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
- if (tempf > 0) {
- tempf = 1000.0 / tempf;
- XIChangeDeviceProperty(pDev, prop, float_prop, 32,
- PropModeReplace, 1, &tempf, FALSE);
- } else {
- tempf = xf86SetRealOption(list, "VelocityScale", s->corr_mul);
- XIChangeDeviceProperty(pDev, prop, float_prop, 32,
- PropModeReplace, 1, &tempf, FALSE);
- }
-
- tempi = xf86SetIntOption(list, "VelocityTrackerCount", -1);
- if (tempi > 1)
- InitTrackers(s, tempi);
-
- s->initial_range = xf86SetIntOption(list, "VelocityInitialRange",
- s->initial_range);
-
- s->max_diff = xf86SetRealOption(list, "VelocityAbsDiff", s->max_diff);
-
- tempf = xf86SetRealOption(list, "VelocityRelDiff", -1);
- if (tempf >= 0) {
- xf86Msg(X_CONFIG, "%s: (accel) max rel. velocity difference: %.1f%%\n",
- devname, tempf*100.0);
- s->max_rel_diff = tempf;
- }
-
- /* Configure softening. If const deceleration is used, this is expected
- * to provide better subpixel information so we enable
- * softening by default only if ConstantDeceleration is not used
- */
- s->use_softening = xf86SetBoolOption(list, "Softening",
- s->const_acceleration == 1.0);
-
- s->average_accel = xf86SetBoolOption(list, "AccelerationProfileAveraging",
- s->average_accel);
-
- s->reset_time = xf86SetIntOption(list, "VelocityReset", s->reset_time);
-}
-
-static void
-ApplyAccelerationSettings(DeviceIntPtr dev){
- int scheme, i;
- DeviceVelocityPtr pVel;
- InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate;
- char* schemeStr;
-
- if (dev->valuator && dev->ptrfeed) {
- schemeStr = xf86SetStrOption(pInfo->options, "AccelerationScheme", "");
-
- scheme = dev->valuator->accelScheme.number;
-
- if (!xf86NameCmp(schemeStr, "predictable"))
- scheme = PtrAccelPredictable;
-
- if (!xf86NameCmp(schemeStr, "lightweight"))
- scheme = PtrAccelLightweight;
-
- if (!xf86NameCmp(schemeStr, "none"))
- scheme = PtrAccelNoOp;
-
- /* reinit scheme if needed */
- if (dev->valuator->accelScheme.number != scheme) {
- if (dev->valuator->accelScheme.AccelCleanupProc) {
- dev->valuator->accelScheme.AccelCleanupProc(dev);
- }
-
- if (InitPointerAccelerationScheme(dev, scheme)) {
- xf86Msg(X_CONFIG, "%s: (accel) selected scheme %s/%i\n",
- pInfo->name, schemeStr, scheme);
- } else {
- xf86Msg(X_CONFIG, "%s: (accel) could not init scheme %s\n",
- pInfo->name, schemeStr);
- scheme = dev->valuator->accelScheme.number;
- }
- } else {
- xf86Msg(X_CONFIG, "%s: (accel) keeping acceleration scheme %i\n",
- pInfo->name, scheme);
- }
-
- free(schemeStr);
-
- /* process special configuration */
- switch (scheme) {
- case PtrAccelPredictable:
- pVel = GetDevicePredictableAccelData(dev);
- ProcessVelocityConfiguration (dev, pInfo->name, pInfo->options,
- pVel);
- break;
- }
-
- i = xf86SetIntOption(pInfo->options, "AccelerationNumerator",
- dev->ptrfeed->ctrl.num);
- if (i >= 0)
- dev->ptrfeed->ctrl.num = i;
-
- i = xf86SetIntOption(pInfo->options, "AccelerationDenominator",
- dev->ptrfeed->ctrl.den);
- if (i > 0)
- dev->ptrfeed->ctrl.den = i;
-
- i = xf86SetIntOption(pInfo->options, "AccelerationThreshold",
- dev->ptrfeed->ctrl.threshold);
- if (i >= 0)
- dev->ptrfeed->ctrl.threshold = i;
-
- xf86Msg(X_CONFIG, "%s: (accel) acceleration factor: %.3f\n",
- pInfo->name, ((float)dev->ptrfeed->ctrl.num)/
- ((float)dev->ptrfeed->ctrl.den));
- xf86Msg(X_CONFIG, "%s: (accel) acceleration threshold: %i\n",
- pInfo->name, dev->ptrfeed->ctrl.threshold);
- }
-}
-
-/***********************************************************************
- *
- * xf86ProcessCommonOptions --
- *
- * Process global options.
- *
- ***********************************************************************
- */
-void
-xf86ProcessCommonOptions(InputInfoPtr pInfo,
- pointer list)
-{
- if (xf86SetBoolOption(list, "Floating", 0) ||
- !xf86SetBoolOption(list, "AlwaysCore", 1) ||
- !xf86SetBoolOption(list, "SendCoreEvents", 1) ||
- !xf86SetBoolOption(list, "CorePointer", 1) ||
- !xf86SetBoolOption(list, "CoreKeyboard", 1)) {
- xf86Msg(X_CONFIG, "%s: doesn't report core events\n", pInfo->name);
- } else {
- pInfo->flags |= XI86_ALWAYS_CORE;
- xf86Msg(X_CONFIG, "%s: always reports core events\n", pInfo->name);
- }
-}
-
-/***********************************************************************
- *
- * xf86ActivateDevice --
- *
- * Initialize an input device.
- *
- * Returns TRUE on success, or FALSE otherwise.
- ***********************************************************************
- */
-static DeviceIntPtr
-xf86ActivateDevice(InputInfoPtr pInfo)
-{
- DeviceIntPtr dev;
- Atom atom;
-
- dev = AddInputDevice(serverClient, pInfo->device_control, TRUE);
-
- if (dev == NULL)
- {
- xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n",
- pInfo->name);
- pInfo->dev = NULL;
- return NULL;
- }
-
- atom = MakeAtom(pInfo->type_name, strlen(pInfo->type_name), TRUE);
- AssignTypeAndName(dev, atom, pInfo->name);
- dev->public.devicePrivate = pInfo;
- pInfo->dev = dev;
-
- dev->coreEvents = pInfo->flags & XI86_ALWAYS_CORE;
- dev->type = SLAVE;
- dev->spriteInfo->spriteOwner = FALSE;
-
- dev->config_info = xf86SetStrOption(pInfo->options, "config_info", NULL);
-
- if (serverGeneration == 1)
- xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
- pInfo->name, pInfo->type_name);
-
- return dev;
-}
-
-/****************************************************************************
- *
- * Caller: ProcXSetDeviceMode
- *
- * Change the mode of an extension device.
- * This function is used to change the mode of a device from reporting
- * relative motion to reporting absolute positional information, and
- * vice versa.
- * The default implementation below is that no such devices are supported.
- *
- ***********************************************************************
- */
-
-int
-SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode)
-{
- InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate;
-
- if (pInfo->switch_mode) {
- return (*pInfo->switch_mode)(client, dev, mode);
- }
- else
- return BadMatch;
-}
-
-
-/***********************************************************************
- *
- * Caller: ProcXSetDeviceValuators
- *
- * Set the value of valuators on an extension input device.
- * This function is used to set the initial value of valuators on
- * those input devices that are capable of reporting either relative
- * motion or an absolute position, and allow an initial position to be set.
- * The default implementation below is that no such devices are supported.
- *
- ***********************************************************************
- */
-
-int
-SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators,
- int first_valuator, int num_valuators)
-{
- InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate;
-
- if (pInfo->set_device_valuators)
- return (*pInfo->set_device_valuators)(pInfo, valuators, first_valuator,
- num_valuators);
-
- return BadMatch;
-}
-
-
-/***********************************************************************
- *
- * Caller: ProcXChangeDeviceControl
- *
- * Change the specified device controls on an extension input device.
- *
- ***********************************************************************
- */
-
-int
-ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control)
-{
- InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate;
-
- if (!pInfo->control_proc) {
- switch (control->control) {
- case DEVICE_CORE:
- case DEVICE_ABS_CALIB:
- case DEVICE_ABS_AREA:
- return BadMatch;
- case DEVICE_RESOLUTION:
- case DEVICE_ENABLE:
- return Success;
- default:
- return BadMatch;
- }
- }
- else {
- return (*pInfo->control_proc)(pInfo, control);
- }
-}
-
-/*
- * Get the operating system name from uname and store it statically to avoid
- * repeating the system call each time MatchOS is checked.
- */
-static const char *
-HostOS(void)
-{
-#ifdef HAVE_SYS_UTSNAME_H
- struct utsname name;
- static char host_os[sizeof(name.sysname)] = "";
-
- if (*host_os == '\0') {
- if (uname(&name) >= 0)
- strcpy(host_os, name.sysname);
- else {
- strncpy(host_os, "unknown", sizeof(host_os));
- host_os[sizeof(host_os)-1] = '\0';
- }
- }
- return host_os;
-#else
- return "";
-#endif
-}
-
-static int
-match_substring(const char *attr, const char *pattern)
-{
- return (strstr(attr, pattern)) ? 0 : -1;
-}
-
-#ifdef HAVE_FNMATCH_H
-static int
-match_pattern(const char *attr, const char *pattern)
-{
- return fnmatch(pattern, attr, 0);
-}
-#else
-#define match_pattern match_substring
-#endif
-
-#ifdef HAVE_FNMATCH_H
-static int
-match_path_pattern(const char *attr, const char *pattern)
-{
- return fnmatch(pattern, attr, FNM_PATHNAME);
-}
-#else
-#define match_path_pattern match_substring
-#endif
-
-/*
- * Match an attribute against a list of NULL terminated arrays of patterns.
- * If a pattern in each list entry is matched, return TRUE.
- */
-static Bool
-MatchAttrToken(const char *attr, struct list *patterns,
- int (*compare)(const char *attr, const char *pattern))
-{
- const xf86MatchGroup *group;
-
- /* If there are no patterns, accept the match */
- if (list_is_empty(patterns))
- return TRUE;
-
- /* If there are patterns but no attribute, reject the match */
- if (!attr)
- return FALSE;
-
- /*
- * Otherwise, iterate the list of patterns ensuring each entry has a
- * match. Each list entry is a separate Match line of the same type.
- */
- list_for_each_entry(group, patterns, entry) {
- char * const *cur;
- Bool match = FALSE;
-
- for (cur = group->values; *cur; cur++)
- if ((*compare)(attr, *cur) == 0) {
- match = TRUE;
- break;
- }
- if (!match)
- return FALSE;
- }
-
- /* All the entries in the list matched the attribute */
- return TRUE;
-}
-
-/*
- * Classes without any Match statements match all devices. Otherwise, all
- * statements must match.
- */
-static Bool
-InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev,
- const InputAttributes *attrs)
-{
- /* MatchProduct substring */
- if (!MatchAttrToken(attrs->product, &iclass->match_product, match_substring))
- return FALSE;
-
- /* MatchVendor substring */
- if (!MatchAttrToken(attrs->vendor, &iclass->match_vendor, match_substring))
- return FALSE;
-
- /* MatchDevicePath pattern */
- if (!MatchAttrToken(attrs->device, &iclass->match_device, match_path_pattern))
- return FALSE;
-
- /* MatchOS case-insensitive string */
- if (!MatchAttrToken(HostOS(), &iclass->match_os, strcasecmp))
- return FALSE;
-
- /* MatchPnPID pattern */
- if (!MatchAttrToken(attrs->pnp_id, &iclass->match_pnpid, match_pattern))
- return FALSE;
-
- /* MatchUSBID pattern */
- if (!MatchAttrToken(attrs->usb_id, &iclass->match_usbid, match_pattern))
- return FALSE;
-
- /* MatchDriver string */
- if (!MatchAttrToken(idev->driver, &iclass->match_driver, strcmp))
- return FALSE;
-
- /*
- * MatchTag string
- * See if any of the device's tags match any of the MatchTag tokens.
- */
- if (!list_is_empty(&iclass->match_tag)) {
- char * const *tag;
- Bool match;
-
- if (!attrs->tags)
- return FALSE;
- for (tag = attrs->tags, match = FALSE; *tag; tag++) {
- if (MatchAttrToken(*tag, &iclass->match_tag, strcmp)) {
- match = TRUE;
- break;
- }
- }
- if (!match)
- return FALSE;
- }
-
- /* MatchIs* booleans */
- if (iclass->is_keyboard.set &&
- iclass->is_keyboard.val != !!(attrs->flags & ATTR_KEYBOARD))
- return FALSE;
- if (iclass->is_pointer.set &&
- iclass->is_pointer.val != !!(attrs->flags & ATTR_POINTER))
- return FALSE;
- if (iclass->is_joystick.set &&
- iclass->is_joystick.val != !!(attrs->flags & ATTR_JOYSTICK))
- return FALSE;
- if (iclass->is_tablet.set &&
- iclass->is_tablet.val != !!(attrs->flags & ATTR_TABLET))
- return FALSE;
- if (iclass->is_touchpad.set &&
- iclass->is_touchpad.val != !!(attrs->flags & ATTR_TOUCHPAD))
- return FALSE;
- if (iclass->is_touchscreen.set &&
- iclass->is_touchscreen.val != !!(attrs->flags & ATTR_TOUCHSCREEN))
- return FALSE;
-
- return TRUE;
-}
-
-/*
- * Merge in any InputClass configurations. Options in each InputClass
- * section have more priority than the original device configuration as
- * well as any previous InputClass sections.
- */
-static int
-MergeInputClasses(const InputInfoPtr idev, const InputAttributes *attrs)
-{
- XF86ConfInputClassPtr cl;
- XF86OptionPtr classopts;
-
- for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
- if (!InputClassMatches(cl, idev, attrs))
- continue;
-
- /* Collect class options and driver settings */
- classopts = xf86optionListDup(cl->option_lst);
- if (cl->driver) {
- free(idev->driver);
- idev->driver = xstrdup(cl->driver);
- if (!idev->driver) {
- xf86Msg(X_ERROR, "Failed to allocate memory while merging "
- "InputClass configuration");
- return BadAlloc;
- }
- classopts = xf86ReplaceStrOption(classopts, "driver",
- idev->driver);
- }
-
- /* Apply options to device with InputClass settings preferred. */
- xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n",
- idev->name, cl->identifier);
- idev->options = xf86optionListMerge(idev->options, classopts);
- }
-
- return Success;
-}
-
-/*
- * Iterate the list of classes and look for Option "Ignore". Return the
- * value of the last matching class and holler when returning TRUE.
- */
-static Bool
-IgnoreInputClass(const InputInfoPtr idev, const InputAttributes *attrs)
-{
- XF86ConfInputClassPtr cl;
- Bool ignore = FALSE;
- const char *ignore_class;
-
- for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
- if (!InputClassMatches(cl, idev, attrs))
- continue;
- if (xf86findOption(cl->option_lst, "Ignore")) {
- ignore = xf86CheckBoolOption(cl->option_lst, "Ignore", FALSE);
- ignore_class = cl->identifier;
- }
- }
-
- if (ignore)
- xf86Msg(X_CONFIG, "%s: Ignoring device from InputClass \"%s\"\n",
- idev->name, ignore_class);
- return ignore;
-}
-
-InputInfoPtr
-xf86AllocateInput(void)
-{
- InputInfoPtr pInfo;
-
- pInfo = calloc(sizeof(*pInfo), 1);
- if (!pInfo)
- return NULL;
-
- pInfo->fd = -1;
- pInfo->type_name = "UNKNOWN";
-
- return pInfo;
-}
-
-/* Append InputInfoRec to the tail of xf86InputDevs. */
-static void
-xf86AddInput(InputDriverPtr drv, InputInfoPtr pInfo)
-{
- InputInfoPtr *prev = NULL;
-
- pInfo->drv = drv;
- pInfo->module = DuplicateModule(drv->module, NULL);
-
- for (prev = &xf86InputDevs; *prev; prev = &(*prev)->next)
- ;
-
- *prev = pInfo;
- pInfo->next = NULL;
-
- xf86CollectInputOptions(pInfo, (const char**)drv->default_options);
- xf86OptionListReport(pInfo->options);
- xf86ProcessCommonOptions(pInfo, pInfo->options);
-}
-
-/*
- * Remove an entry from xf86InputDevs and free all the device's information.
- */
-void
-xf86DeleteInput(InputInfoPtr pInp, int flags)
-{
- /* First check if the inputdev is valid. */
- if (pInp == NULL)
- return;
-
- if (pInp->module)
- UnloadModule(pInp->module);
-
- /* This should *really* be handled in drv->UnInit(dev) call instead, but
- * if the driver forgets about it make sure we free it or at least crash
- * with flying colors */
- free(pInp->private);
-
- FreeInputAttributes(pInp->attrs);
-
- /* Remove the entry from the list. */
- if (pInp == xf86InputDevs)
- xf86InputDevs = pInp->next;
- else {
- InputInfoPtr p = xf86InputDevs;
- while (p && p->next != pInp)
- p = p->next;
- if (p)
- p->next = pInp->next;
- /* Else the entry wasn't in the xf86InputDevs list (ignore this). */
- }
-
- free(pInp->driver);
- free(pInp->name);
- xf86optionListFree(pInp->options);
- free(pInp);
-}
-
-/*
- * Apply backend-specific initialization. Invoked after ActiveteDevice(),
- * i.e. after the driver successfully completed DEVICE_INIT and the device
- * is advertised.
- * @param dev the device
- * @return Success or an error code
- */
-static int
-xf86InputDevicePostInit(DeviceIntPtr dev) {
- ApplyAccelerationSettings(dev);
- return Success;
-}
-
-/**
- * Create a new input device, activate and enable it.
- *
- * Possible return codes:
- * BadName .. a bad driver name was supplied.
- * BadImplementation ... The driver does not have a PreInit function. This
- * is a driver bug.
- * BadMatch .. device initialization failed.
- * BadAlloc .. too many input devices
- *
- * @param idev The device, already set up with identifier, driver, and the
- * options.
- * @param pdev Pointer to the new device, if Success was reported.
- * @param enable Enable the device after activating it.
- *
- * @return Success or an error code
- */
-_X_INTERNAL int
-xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
-{
- InputDriverPtr drv = NULL;
- DeviceIntPtr dev = NULL;
- int rval;
-
- /* Memory leak for every attached device if we don't
- * test if the module is already loaded first */
- drv = xf86LookupInputDriver(pInfo->driver);
- if (!drv)
- if (xf86LoadOneModule(pInfo->driver, NULL))
- drv = xf86LookupInputDriver(pInfo->driver);
- if (!drv) {
- xf86Msg(X_ERROR, "No input driver matching `%s'\n", pInfo->driver);
- rval = BadName;
- goto unwind;
- }
-
- xf86Msg(X_INFO, "Using input driver '%s' for '%s'\n", drv->driverName, pInfo->name);
-
- if (!drv->PreInit) {
- xf86Msg(X_ERROR,
- "Input driver `%s' has no PreInit function (ignoring)\n",
- drv->driverName);
- rval = BadImplementation;
- goto unwind;
- }
-
- xf86AddInput(drv, pInfo);
-
- rval = drv->PreInit(drv, pInfo, 0);
-
- if (rval != Success) {
- xf86Msg(X_ERROR, "PreInit returned %d for \"%s\"\n", rval, pInfo->name);
- goto unwind;
- }
-
- if (!(dev = xf86ActivateDevice(pInfo)))
- {
- rval = BadAlloc;
- goto unwind;
- }
-
- rval = ActivateDevice(dev, TRUE);
- if (rval != Success)
- {
- xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name);
- RemoveDevice(dev, TRUE);
- goto unwind;
- }
-
- rval = xf86InputDevicePostInit(dev);
- if (rval != Success)
- {
- xf86Msg(X_ERROR, "Couldn't post-init device \"%s\"\n", pInfo->name);
- RemoveDevice(dev, TRUE);
- goto unwind;
- }
-
- /* Enable it if it's properly initialised and we're currently in the VT */
- if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema)
- {
- OsBlockSignals();
- EnableDevice(dev, TRUE);
- if (!dev->enabled)
- {
- OsReleaseSignals();
- xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name);
- rval = BadMatch;
- goto unwind;
- }
- /* send enter/leave event, update sprite window */
- CheckMotion(NULL, dev);
- OsReleaseSignals();
- }
-
- *pdev = dev;
- return Success;
-
-unwind:
- if(pInfo) {
- if(drv && drv->UnInit)
- drv->UnInit(drv, pInfo, 0);
- else
- xf86DeleteInput(pInfo, 0);
- }
- return rval;
-}
-
-int
-NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
- DeviceIntPtr *pdev)
-{
- InputInfoPtr pInfo = NULL;
- InputOption *option = NULL;
- int rval = Success;
- int is_auto = 0;
-
- pInfo = xf86AllocateInput();
- if (!pInfo)
- return BadAlloc;
-
- for (option = options; option; option = option->next) {
- if (strcasecmp(option->key, "driver") == 0) {
- if (pInfo->driver) {
- rval = BadRequest;
- goto unwind;
- }
- pInfo->driver = xstrdup(option->value);
- if (!pInfo->driver) {
- rval = BadAlloc;
- goto unwind;
- }
- }
-
- if (strcasecmp(option->key, "name") == 0 ||
- strcasecmp(option->key, "identifier") == 0) {
- if (pInfo->name) {
- rval = BadRequest;
- goto unwind;
- }
- pInfo->name = xstrdup(option->value);
- 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)) {
- is_auto = 1;
- if (!xf86Info.autoAddDevices) {
- rval = BadMatch;
- goto unwind;
- }
- }
- }
-
- 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;
- }
-
- /* Apply InputClass settings */
- if (attrs) {
- if (IgnoreInputClass(pInfo, attrs)) {
- rval = BadIDChoice;
- goto unwind;
- }
-
- rval = MergeInputClasses(pInfo, attrs);
- if (rval != Success)
- goto unwind;
-
- pInfo->attrs = DuplicateInputAttributes(attrs);
- }
-
- if (!pInfo->driver || !pInfo->name) {
- xf86Msg(X_INFO, "No input driver/identifier specified (ignoring)\n");
- rval = BadRequest;
- goto unwind;
- }
-
- if (!pInfo->name) {
- xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n");
- rval = BadMatch;
- goto unwind;
- }
-
- rval = xf86NewInputDevice(pInfo, pdev,
- (!is_auto || (is_auto && xf86Info.autoEnableDevices)));
-
- return rval;
-
-unwind:
- if (is_auto && !xf86Info.autoAddDevices)
- xf86Msg(X_INFO, "AutoAddDevices is off - not adding device.\n");
- xf86DeleteInput(pInfo, 0);
- return rval;
-}
-
-void
-DeleteInputDeviceRequest(DeviceIntPtr pDev)
-{
- InputInfoPtr pInfo = (InputInfoPtr) pDev->public.devicePrivate;
- InputDriverPtr drv = NULL;
- Bool isMaster = IsMaster(pDev);
-
- if (pInfo) /* need to get these before RemoveDevice */
- drv = pInfo->drv;
-
- OsBlockSignals();
- RemoveDevice(pDev, TRUE);
-
- if (!isMaster && pInfo != NULL)
- {
- if(drv->UnInit)
- drv->UnInit(drv, pInfo, 0);
- else
- xf86DeleteInput(pInfo, 0);
- }
- OsReleaseSignals();
-}
-
-/*
- * convenient functions to post events
- */
-
-void
-xf86PostMotionEvent(DeviceIntPtr device,
- int is_absolute,
- int first_valuator,
- int num_valuators,
- ...)
-{
- va_list var;
- int i = 0;
- ValuatorMask mask;
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- valuator_mask_zero(&mask);
- va_start(var, num_valuators);
- for (i = 0; i < num_valuators; i++)
- valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
- va_end(var);
-
- xf86PostMotionEventM(device, is_absolute, &mask);
-}
-
-void
-xf86PostMotionEventP(DeviceIntPtr device,
- int is_absolute,
- int first_valuator,
- int num_valuators,
- const int *valuators)
-{
- ValuatorMask mask;
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators);
- xf86PostMotionEventM(device, is_absolute, &mask);
-}
-
-void
-xf86PostMotionEventM(DeviceIntPtr device,
- int is_absolute,
- const ValuatorMask *mask)
-{
- int i = 0, nevents = 0;
- int flags = 0;
-
- if (valuator_mask_num_valuators(mask) > 0)
- {
- if (is_absolute)
- flags = POINTER_ABSOLUTE;
- else
- flags = POINTER_RELATIVE | POINTER_ACCELERATE;
- }
-
-#if XFreeXDGA
- /* The evdev driver may not always send all axes across. */
- if (valuator_mask_isset(mask, 0) ||
- valuator_mask_isset(mask, 1))
- if (miPointerGetScreen(device)) {
- int index = miPointerGetScreen(device)->myNum;
- int dx = 0, dy = 0;
-
- if (valuator_mask_isset(mask, 0))
- {
- dx = valuator_mask_get(mask, 0);
- if (is_absolute)
- dx -= device->last.valuators[0];
- }
-
- if (valuator_mask_isset(mask, 1))
- {
- dy = valuator_mask_get(mask, 1);
- if (is_absolute)
- dy -= device->last.valuators[1];
- }
-
- if (DGAStealMotionEvent(device, index, dx, dy))
- return;
- }
-#endif
-
- nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, flags, mask);
-
- for (i = 0; i < nevents; i++) {
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
- }
-}
-
-void
-xf86PostProximityEvent(DeviceIntPtr device,
- int is_in,
- int first_valuator,
- int num_valuators,
- ...)
-{
- va_list var;
- int i;
- ValuatorMask mask;
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- valuator_mask_zero(&mask);
- va_start(var, num_valuators);
- for (i = 0; i < num_valuators; i++)
- valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
- va_end(var);
-
- xf86PostProximityEventM(device, is_in, &mask);
-}
-
-void
-xf86PostProximityEventP(DeviceIntPtr device,
- int is_in,
- int first_valuator,
- int num_valuators,
- const int *valuators)
-{
- ValuatorMask mask;
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators);
- xf86PostProximityEventM(device, is_in, &mask);
-}
-
-void
-xf86PostProximityEventM(DeviceIntPtr device,
- int is_in,
- const ValuatorMask *mask)
-{
- int i, nevents;
-
- nevents = GetProximityEvents(xf86Events, device,
- is_in ? ProximityIn : ProximityOut, mask);
- for (i = 0; i < nevents; i++)
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-
-}
-
-void
-xf86PostButtonEvent(DeviceIntPtr device,
- int is_absolute,
- int button,
- int is_down,
- int first_valuator,
- int num_valuators,
- ...)
-{
- va_list var;
- ValuatorMask mask;
- int i = 0;
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- valuator_mask_zero(&mask);
-
- va_start(var, num_valuators);
- for (i = 0; i < num_valuators; i++)
- valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
- va_end(var);
-
- xf86PostButtonEventM(device, is_absolute, button, is_down, &mask);
-}
-
-void
-xf86PostButtonEventP(DeviceIntPtr device,
- int is_absolute,
- int button,
- int is_down,
- int first_valuator,
- int num_valuators,
- const int *valuators)
-{
- ValuatorMask mask;
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators);
- xf86PostButtonEventM(device, is_absolute, button, is_down, &mask);
-}
-
-void
-xf86PostButtonEventM(DeviceIntPtr device,
- int is_absolute,
- int button,
- int is_down,
- const ValuatorMask *mask)
-{
- int i = 0, nevents = 0;
- int flags = 0;
-
- if (valuator_mask_num_valuators(mask) > 0)
- {
- if (is_absolute)
- flags = POINTER_ABSOLUTE;
- else
- flags = POINTER_RELATIVE | POINTER_ACCELERATE;
- }
-
-#if XFreeXDGA
- if (miPointerGetScreen(device)) {
- int index = miPointerGetScreen(device)->myNum;
-
- if (DGAStealButtonEvent(device, index, button, is_down))
- return;
- }
-#endif
-
- nevents = GetPointerEvents(xf86Events, device,
- is_down ? ButtonPress : ButtonRelease, button,
- flags, mask);
-
- for (i = 0; i < nevents; i++)
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-
-}
-
-void
-xf86PostKeyEvent(DeviceIntPtr device,
- unsigned int key_code,
- int is_down,
- int is_absolute,
- int first_valuator,
- int num_valuators,
- ...)
-{
- va_list var;
- int i = 0;
- ValuatorMask mask;
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- valuator_mask_zero(&mask);
-
- va_start(var, num_valuators);
- for (i = 0; i < num_valuators; i++)
- valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
- va_end(var);
-
- xf86PostKeyEventM(device, key_code, is_down, is_absolute, &mask);
-}
-
-void
-xf86PostKeyEventP(DeviceIntPtr device,
- unsigned int key_code,
- int is_down,
- int is_absolute,
- int first_valuator,
- int num_valuators,
- const int *valuators)
-{
- ValuatorMask mask;
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators);
- xf86PostKeyEventM(device, key_code, is_down, is_absolute, &mask);
-}
-
-void
-xf86PostKeyEventM(DeviceIntPtr device,
- unsigned int key_code,
- int is_down,
- int is_absolute,
- const ValuatorMask *mask)
-{
- int i = 0, nevents = 0;
-
-#if XFreeXDGA
- DeviceIntPtr pointer;
-
- /* Some pointers send key events, paired device is wrong then. */
- pointer = IsPointerDevice(device) ? device : GetPairedDevice(device);
- if (miPointerGetScreen(pointer)) {
- int index = miPointerGetScreen(pointer)->myNum;
-
- if (DGAStealKeyEvent(device, index, key_code, is_down))
- return;
- }
-#endif
-
- nevents = GetKeyboardEvents(xf86Events, device,
- is_down ? KeyPress : KeyRelease,
- key_code, mask);
-
- for (i = 0; i < nevents; i++)
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-}
-
-void
-xf86PostKeyboardEvent(DeviceIntPtr device,
- unsigned int key_code,
- int is_down)
-{
- ValuatorMask mask;
-
- valuator_mask_zero(&mask);
- xf86PostKeyEventM(device, key_code, is_down, 0, &mask);
-}
-
-InputInfoPtr
-xf86FirstLocalDevice(void)
-{
- return xf86InputDevs;
-}
-
-/*
- * Cx - raw data from touch screen
- * to_max - scaled highest dimension
- * (remember, this is of rows - 1 because of 0 origin)
- * to_min - scaled lowest dimension
- * from_max - highest raw value from touch screen calibration
- * from_min - lowest raw value from touch screen calibration
- *
- * This function is the same for X or Y coordinates.
- * You may have to reverse the high and low values to compensate for
- * different orgins on the touch screen vs X.
- *
- * e.g. to scale from device coordinates into screen coordinates, call
- * xf86ScaleAxis(x, 0, screen_width, dev_min, dev_max);
- */
-
-int
-xf86ScaleAxis(int Cx,
- int to_max,
- int to_min,
- int from_max,
- int from_min )
-{
- int X;
- int64_t to_width = to_max - to_min;
- int64_t from_width = from_max - from_min;
-
- if (from_width) {
- X = (int)(((to_width * (Cx - from_min)) / from_width) + to_min);
- }
- else {
- X = 0;
- ErrorF ("Divide by Zero in xf86ScaleAxis\n");
- }
-
- if (X > to_max)
- X = to_max;
- if (X < to_min)
- X = to_min;
-
- return X;
-}
-
-/*
- * This function checks the given screen against the current screen and
- * makes changes if appropriate. It should be called from an XInput driver's
- * ReadInput function before any events are posted, if the device is screen
- * specific like a touch screen.
- */
-void
-xf86XInputSetScreen(InputInfoPtr pInfo,
- int screen_number,
- int x,
- int y)
-{
- if (miPointerGetScreen(pInfo->dev) !=
- screenInfo.screens[screen_number]) {
- miPointerSetScreen(pInfo->dev, screen_number, x, y);
- }
-}
-
-
-void
-xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
- int resolution, int min_res, int max_res, int mode)
-{
- if (!dev || !dev->valuator)
- return;
-
- InitValuatorAxisStruct(dev, axnum, label, minval, maxval, resolution, min_res,
- max_res, mode);
-}
-
-/*
- * Set the valuator values to be in synch with dix/event.c
- * DefineInitialRootWindow().
- */
-void
-xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
-{
- if (axnum == 0) {
- dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
- dev->last.valuators[0] = dev->valuator->axisVal[0];
- }
- else if (axnum == 1) {
- dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
- dev->last.valuators[1] = dev->valuator->axisVal[1];
- }
-}
-
-
-/**
- * Deactivate a device. Call this function from the driver if you receive a
- * read error or something else that spoils your day.
- * Device will be moved to the off_devices list, but it will still be there
- * until you really clean up after it.
- * Notifies the client about an inactive device.
- *
- * @param panic True if device is unrecoverable and needs to be removed.
- */
-void
-xf86DisableDevice(DeviceIntPtr dev, Bool panic)
-{
- if(!panic)
- {
- DisableDevice(dev, TRUE);
- } else
- {
- SendDevicePresenceEvent(dev->id, DeviceUnrecoverable);
- DeleteInputDeviceRequest(dev);
- }
-}
-
-/**
- * Reactivate a device. Call this function from the driver if you just found
- * out that the read error wasn't quite that bad after all.
- * Device will be re-activated, and an event sent to the client.
- */
-void
-xf86EnableDevice(DeviceIntPtr dev)
-{
- EnableDevice(dev, TRUE);
-}
-
-/* end of xf86Xinput.c */
+/*
+ * 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,
+ * 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).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/Xfuncproto.h>
+#include <X11/Xmd.h>
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include <X11/Xatom.h>
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Config.h"
+#include "xf86Xinput.h"
+#include "xf86Optrec.h"
+#include "mipointer.h"
+#include "extinit.h"
+#include "loaderProcs.h"
+
+#include "exevents.h" /* AddInputDevice */
+#include "exglobals.h"
+#include "eventstr.h"
+#include "inpututils.h"
+
+#include <string.h> /* InputClassMatches */
+#ifdef HAVE_FNMATCH_H
+#include <fnmatch.h>
+#endif
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+
+#include <stdarg.h>
+#include <stdint.h> /* for int64_t */
+
+#include "mi.h"
+
+#include <ptrveloc.h> /* dix pointer acceleration */
+#include <xserver-properties.h>
+
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+#include "xkbsrv.h"
+
+/* Valuator verification macro */
+#define XI_VERIFY_VALUATORS(num_valuators) \
+ if (num_valuators > MAX_VALUATORS) { \
+ xf86Msg(X_ERROR, "%s: num_valuator %d is greater than" \
+ " MAX_VALUATORS\n", __FUNCTION__, num_valuators); \
+ return; \
+ }
+
+EventListPtr xf86Events = NULL;
+
+static int
+xf86InputDevicePostInit(DeviceIntPtr dev);
+
+/**
+ * Eval config and modify DeviceVelocityRec accordingly
+ */
+static void
+ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list,
+ DeviceVelocityPtr s)
+{
+ int tempi;
+ float tempf;
+ Atom float_prop = XIGetKnownProperty(XATOM_FLOAT);
+ Atom prop;
+
+ if(!s)
+ return;
+
+ /* common settings (available via device properties) */
+ tempf = xf86SetRealOption(list, "ConstantDeceleration", 1.0);
+ if (tempf > 1.0) {
+ xf86Msg(X_CONFIG, "%s: (accel) constant deceleration by %.1f\n",
+ devname, tempf);
+ prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
+ XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+ PropModeReplace, 1, &tempf, FALSE);
+ }
+
+ tempf = xf86SetRealOption(list, "AdaptiveDeceleration", 1.0);
+ if (tempf > 1.0) {
+ xf86Msg(X_CONFIG, "%s: (accel) adaptive deceleration by %.1f\n",
+ devname, tempf);
+ prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
+ XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+ PropModeReplace, 1, &tempf, FALSE);
+ }
+
+ /* select profile by number */
+ tempi = xf86SetIntOption(list, "AccelerationProfile",
+ s->statistics.profile_number);
+
+ prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
+ if (XIChangeDeviceProperty(pDev, prop, XA_INTEGER, 32,
+ PropModeReplace, 1, &tempi, FALSE) == Success) {
+ xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i\n", devname,
+ tempi);
+ } else {
+ xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i is unknown\n",
+ devname, tempi);
+ }
+
+ /* set scaling */
+ tempf = xf86SetRealOption(list, "ExpectedRate", 0);
+ prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
+ if (tempf > 0) {
+ tempf = 1000.0 / tempf;
+ XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+ PropModeReplace, 1, &tempf, FALSE);
+ } else {
+ tempf = xf86SetRealOption(list, "VelocityScale", s->corr_mul);
+ XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+ PropModeReplace, 1, &tempf, FALSE);
+ }
+
+ tempi = xf86SetIntOption(list, "VelocityTrackerCount", -1);
+ if (tempi > 1)
+ InitTrackers(s, tempi);
+
+ s->initial_range = xf86SetIntOption(list, "VelocityInitialRange",
+ s->initial_range);
+
+ s->max_diff = xf86SetRealOption(list, "VelocityAbsDiff", s->max_diff);
+
+ tempf = xf86SetRealOption(list, "VelocityRelDiff", -1);
+ if (tempf >= 0) {
+ xf86Msg(X_CONFIG, "%s: (accel) max rel. velocity difference: %.1f%%\n",
+ devname, tempf*100.0);
+ s->max_rel_diff = tempf;
+ }
+
+ /* Configure softening. If const deceleration is used, this is expected
+ * to provide better subpixel information so we enable
+ * softening by default only if ConstantDeceleration is not used
+ */
+ s->use_softening = xf86SetBoolOption(list, "Softening",
+ s->const_acceleration == 1.0);
+
+ s->average_accel = xf86SetBoolOption(list, "AccelerationProfileAveraging",
+ s->average_accel);
+
+ s->reset_time = xf86SetIntOption(list, "VelocityReset", s->reset_time);
+}
+
+static void
+ApplyAccelerationSettings(DeviceIntPtr dev){
+ int scheme, i;
+ DeviceVelocityPtr pVel;
+ InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate;
+ char* schemeStr;
+
+ if (dev->valuator && dev->ptrfeed) {
+ schemeStr = xf86SetStrOption(pInfo->options, "AccelerationScheme", "");
+
+ scheme = dev->valuator->accelScheme.number;
+
+ if (!xf86NameCmp(schemeStr, "predictable"))
+ scheme = PtrAccelPredictable;
+
+ if (!xf86NameCmp(schemeStr, "lightweight"))
+ scheme = PtrAccelLightweight;
+
+ if (!xf86NameCmp(schemeStr, "none"))
+ scheme = PtrAccelNoOp;
+
+ /* reinit scheme if needed */
+ if (dev->valuator->accelScheme.number != scheme) {
+ if (dev->valuator->accelScheme.AccelCleanupProc) {
+ dev->valuator->accelScheme.AccelCleanupProc(dev);
+ }
+
+ if (InitPointerAccelerationScheme(dev, scheme)) {
+ xf86Msg(X_CONFIG, "%s: (accel) selected scheme %s/%i\n",
+ pInfo->name, schemeStr, scheme);
+ } else {
+ xf86Msg(X_CONFIG, "%s: (accel) could not init scheme %s\n",
+ pInfo->name, schemeStr);
+ scheme = dev->valuator->accelScheme.number;
+ }
+ } else {
+ xf86Msg(X_CONFIG, "%s: (accel) keeping acceleration scheme %i\n",
+ pInfo->name, scheme);
+ }
+
+ free(schemeStr);
+
+ /* process special configuration */
+ switch (scheme) {
+ case PtrAccelPredictable:
+ pVel = GetDevicePredictableAccelData(dev);
+ ProcessVelocityConfiguration (dev, pInfo->name, pInfo->options,
+ pVel);
+ break;
+ }
+
+ i = xf86SetIntOption(pInfo->options, "AccelerationNumerator",
+ dev->ptrfeed->ctrl.num);
+ if (i >= 0)
+ dev->ptrfeed->ctrl.num = i;
+
+ i = xf86SetIntOption(pInfo->options, "AccelerationDenominator",
+ dev->ptrfeed->ctrl.den);
+ if (i > 0)
+ dev->ptrfeed->ctrl.den = i;
+
+ i = xf86SetIntOption(pInfo->options, "AccelerationThreshold",
+ dev->ptrfeed->ctrl.threshold);
+ if (i >= 0)
+ dev->ptrfeed->ctrl.threshold = i;
+
+ xf86Msg(X_CONFIG, "%s: (accel) acceleration factor: %.3f\n",
+ pInfo->name, ((float)dev->ptrfeed->ctrl.num)/
+ ((float)dev->ptrfeed->ctrl.den));
+ xf86Msg(X_CONFIG, "%s: (accel) acceleration threshold: %i\n",
+ pInfo->name, dev->ptrfeed->ctrl.threshold);
+ }
+}
+
+/***********************************************************************
+ *
+ * xf86ProcessCommonOptions --
+ *
+ * Process global options.
+ *
+ ***********************************************************************
+ */
+void
+xf86ProcessCommonOptions(InputInfoPtr pInfo,
+ pointer list)
+{
+ if (xf86SetBoolOption(list, "Floating", 0) ||
+ !xf86SetBoolOption(list, "AlwaysCore", 1) ||
+ !xf86SetBoolOption(list, "SendCoreEvents", 1) ||
+ !xf86SetBoolOption(list, "CorePointer", 1) ||
+ !xf86SetBoolOption(list, "CoreKeyboard", 1)) {
+ xf86Msg(X_CONFIG, "%s: doesn't report core events\n", pInfo->name);
+ } else {
+ pInfo->flags |= XI86_ALWAYS_CORE;
+ xf86Msg(X_CONFIG, "%s: always reports core events\n", pInfo->name);
+ }
+}
+
+/***********************************************************************
+ *
+ * xf86ActivateDevice --
+ *
+ * Initialize an input device.
+ *
+ * Returns TRUE on success, or FALSE otherwise.
+ ***********************************************************************
+ */
+static DeviceIntPtr
+xf86ActivateDevice(InputInfoPtr pInfo)
+{
+ DeviceIntPtr dev;
+ Atom atom;
+
+ dev = AddInputDevice(serverClient, pInfo->device_control, TRUE);
+
+ if (dev == NULL)
+ {
+ xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n",
+ pInfo->name);
+ pInfo->dev = NULL;
+ return NULL;
+ }
+
+ atom = MakeAtom(pInfo->type_name, strlen(pInfo->type_name), TRUE);
+ AssignTypeAndName(dev, atom, pInfo->name);
+ dev->public.devicePrivate = pInfo;
+ pInfo->dev = dev;
+
+ dev->coreEvents = pInfo->flags & XI86_ALWAYS_CORE;
+ dev->type = SLAVE;
+ dev->spriteInfo->spriteOwner = FALSE;
+
+ dev->config_info = xf86SetStrOption(pInfo->options, "config_info", NULL);
+
+ if (serverGeneration == 1)
+ xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
+ pInfo->name, pInfo->type_name);
+
+ return dev;
+}
+
+/****************************************************************************
+ *
+ * Caller: ProcXSetDeviceMode
+ *
+ * Change the mode of an extension device.
+ * This function is used to change the mode of a device from reporting
+ * relative motion to reporting absolute positional information, and
+ * vice versa.
+ * The default implementation below is that no such devices are supported.
+ *
+ ***********************************************************************
+ */
+
+int
+SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode)
+{
+ InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate;
+
+ if (pInfo->switch_mode) {
+ return (*pInfo->switch_mode)(client, dev, mode);
+ }
+ else
+ return BadMatch;
+}
+
+
+/***********************************************************************
+ *
+ * Caller: ProcXSetDeviceValuators
+ *
+ * Set the value of valuators on an extension input device.
+ * This function is used to set the initial value of valuators on
+ * those input devices that are capable of reporting either relative
+ * motion or an absolute position, and allow an initial position to be set.
+ * The default implementation below is that no such devices are supported.
+ *
+ ***********************************************************************
+ */
+
+int
+SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators,
+ int first_valuator, int num_valuators)
+{
+ InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate;
+
+ if (pInfo->set_device_valuators)
+ return (*pInfo->set_device_valuators)(pInfo, valuators, first_valuator,
+ num_valuators);
+
+ return BadMatch;
+}
+
+
+/***********************************************************************
+ *
+ * Caller: ProcXChangeDeviceControl
+ *
+ * Change the specified device controls on an extension input device.
+ *
+ ***********************************************************************
+ */
+
+int
+ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control)
+{
+ InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate;
+
+ if (!pInfo->control_proc) {
+ switch (control->control) {
+ case DEVICE_CORE:
+ case DEVICE_ABS_CALIB:
+ case DEVICE_ABS_AREA:
+ return BadMatch;
+ case DEVICE_RESOLUTION:
+ case DEVICE_ENABLE:
+ return Success;
+ default:
+ return BadMatch;
+ }
+ }
+ else {
+ return (*pInfo->control_proc)(pInfo, control);
+ }
+}
+
+/*
+ * Get the operating system name from uname and store it statically to avoid
+ * repeating the system call each time MatchOS is checked.
+ */
+static const char *
+HostOS(void)
+{
+#ifdef HAVE_SYS_UTSNAME_H
+ struct utsname name;
+ static char host_os[sizeof(name.sysname)] = "";
+
+ if (*host_os == '\0') {
+ if (uname(&name) >= 0)
+ strcpy(host_os, name.sysname);
+ else {
+ strncpy(host_os, "unknown", sizeof(host_os));
+ host_os[sizeof(host_os)-1] = '\0';
+ }
+ }
+ return host_os;
+#else
+ return "";
+#endif
+}
+
+static int
+match_substring(const char *attr, const char *pattern)
+{
+ return (strstr(attr, pattern)) ? 0 : -1;
+}
+
+#ifdef HAVE_FNMATCH_H
+static int
+match_pattern(const char *attr, const char *pattern)
+{
+ return fnmatch(pattern, attr, 0);
+}
+#else
+#define match_pattern match_substring
+#endif
+
+#ifdef HAVE_FNMATCH_H
+static int
+match_path_pattern(const char *attr, const char *pattern)
+{
+ return fnmatch(pattern, attr, FNM_PATHNAME);
+}
+#else
+#define match_path_pattern match_substring
+#endif
+
+/*
+ * Match an attribute against a list of NULL terminated arrays of patterns.
+ * If a pattern in each list entry is matched, return TRUE.
+ */
+static Bool
+MatchAttrToken(const char *attr, struct list *patterns,
+ int (*compare)(const char *attr, const char *pattern))
+{
+ const xf86MatchGroup *group;
+
+ /* If there are no patterns, accept the match */
+ if (list_is_empty(patterns))
+ return TRUE;
+
+ /* If there are patterns but no attribute, reject the match */
+ if (!attr)
+ return FALSE;
+
+ /*
+ * Otherwise, iterate the list of patterns ensuring each entry has a
+ * match. Each list entry is a separate Match line of the same type.
+ */
+ list_for_each_entry(group, patterns, entry) {
+ char * const *cur;
+ Bool match = FALSE;
+
+ for (cur = group->values; *cur; cur++)
+ if ((*compare)(attr, *cur) == 0) {
+ match = TRUE;
+ break;
+ }
+ if (!match)
+ return FALSE;
+ }
+
+ /* All the entries in the list matched the attribute */
+ return TRUE;
+}
+
+/*
+ * Classes without any Match statements match all devices. Otherwise, all
+ * statements must match.
+ */
+static Bool
+InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev,
+ const InputAttributes *attrs)
+{
+ /* MatchProduct substring */
+ if (!MatchAttrToken(attrs->product, &iclass->match_product, match_substring))
+ return FALSE;
+
+ /* MatchVendor substring */
+ if (!MatchAttrToken(attrs->vendor, &iclass->match_vendor, match_substring))
+ return FALSE;
+
+ /* MatchDevicePath pattern */
+ if (!MatchAttrToken(attrs->device, &iclass->match_device, match_path_pattern))
+ return FALSE;
+
+ /* MatchOS case-insensitive string */
+ if (!MatchAttrToken(HostOS(), &iclass->match_os, strcasecmp))
+ return FALSE;
+
+ /* MatchPnPID pattern */
+ if (!MatchAttrToken(attrs->pnp_id, &iclass->match_pnpid, match_pattern))
+ return FALSE;
+
+ /* MatchUSBID pattern */
+ if (!MatchAttrToken(attrs->usb_id, &iclass->match_usbid, match_pattern))
+ return FALSE;
+
+ /* MatchDriver string */
+ if (!MatchAttrToken(idev->driver, &iclass->match_driver, strcmp))
+ return FALSE;
+
+ /*
+ * MatchTag string
+ * See if any of the device's tags match any of the MatchTag tokens.
+ */
+ if (!list_is_empty(&iclass->match_tag)) {
+ char * const *tag;
+ Bool match;
+
+ if (!attrs->tags)
+ return FALSE;
+ for (tag = attrs->tags, match = FALSE; *tag; tag++) {
+ if (MatchAttrToken(*tag, &iclass->match_tag, strcmp)) {
+ match = TRUE;
+ break;
+ }
+ }
+ if (!match)
+ return FALSE;
+ }
+
+ /* MatchIs* booleans */
+ if (iclass->is_keyboard.set &&
+ iclass->is_keyboard.val != !!(attrs->flags & ATTR_KEYBOARD))
+ return FALSE;
+ if (iclass->is_pointer.set &&
+ iclass->is_pointer.val != !!(attrs->flags & ATTR_POINTER))
+ return FALSE;
+ if (iclass->is_joystick.set &&
+ iclass->is_joystick.val != !!(attrs->flags & ATTR_JOYSTICK))
+ return FALSE;
+ if (iclass->is_tablet.set &&
+ iclass->is_tablet.val != !!(attrs->flags & ATTR_TABLET))
+ return FALSE;
+ if (iclass->is_touchpad.set &&
+ iclass->is_touchpad.val != !!(attrs->flags & ATTR_TOUCHPAD))
+ return FALSE;
+ if (iclass->is_touchscreen.set &&
+ iclass->is_touchscreen.val != !!(attrs->flags & ATTR_TOUCHSCREEN))
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * Merge in any InputClass configurations. Options in each InputClass
+ * section have more priority than the original device configuration as
+ * well as any previous InputClass sections.
+ */
+static int
+MergeInputClasses(const InputInfoPtr idev, const InputAttributes *attrs)
+{
+ XF86ConfInputClassPtr cl;
+ XF86OptionPtr classopts;
+
+ for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
+ if (!InputClassMatches(cl, idev, attrs))
+ continue;
+
+ /* Collect class options and driver settings */
+ classopts = xf86optionListDup(cl->option_lst);
+ if (cl->driver) {
+ free(idev->driver);
+ idev->driver = xstrdup(cl->driver);
+ if (!idev->driver) {
+ xf86Msg(X_ERROR, "Failed to allocate memory while merging "
+ "InputClass configuration");
+ return BadAlloc;
+ }
+ classopts = xf86ReplaceStrOption(classopts, "driver",
+ idev->driver);
+ }
+
+ /* Apply options to device with InputClass settings preferred. */
+ xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n",
+ idev->name, cl->identifier);
+ idev->options = xf86optionListMerge(idev->options, classopts);
+ }
+
+ return Success;
+}
+
+/*
+ * Iterate the list of classes and look for Option "Ignore". Return the
+ * value of the last matching class and holler when returning TRUE.
+ */
+static Bool
+IgnoreInputClass(const InputInfoPtr idev, const InputAttributes *attrs)
+{
+ XF86ConfInputClassPtr cl;
+ Bool ignore = FALSE;
+ const char *ignore_class;
+
+ for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
+ if (!InputClassMatches(cl, idev, attrs))
+ continue;
+ if (xf86findOption(cl->option_lst, "Ignore")) {
+ ignore = xf86CheckBoolOption(cl->option_lst, "Ignore", FALSE);
+ ignore_class = cl->identifier;
+ }
+ }
+
+ if (ignore)
+ xf86Msg(X_CONFIG, "%s: Ignoring device from InputClass \"%s\"\n",
+ idev->name, ignore_class);
+ return ignore;
+}
+
+InputInfoPtr
+xf86AllocateInput(void)
+{
+ InputInfoPtr pInfo;
+
+ pInfo = calloc(sizeof(*pInfo), 1);
+ if (!pInfo)
+ return NULL;
+
+ pInfo->fd = -1;
+ pInfo->type_name = "UNKNOWN";
+
+ return pInfo;
+}
+
+/* Append InputInfoRec to the tail of xf86InputDevs. */
+static void
+xf86AddInput(InputDriverPtr drv, InputInfoPtr pInfo)
+{
+ InputInfoPtr *prev = NULL;
+
+ pInfo->drv = drv;
+ pInfo->module = DuplicateModule(drv->module, NULL);
+
+ for (prev = &xf86InputDevs; *prev; prev = &(*prev)->next)
+ ;
+
+ *prev = pInfo;
+ pInfo->next = NULL;
+
+ xf86CollectInputOptions(pInfo, (const char**)drv->default_options);
+ xf86OptionListReport(pInfo->options);
+ xf86ProcessCommonOptions(pInfo, pInfo->options);
+}
+
+/*
+ * Remove an entry from xf86InputDevs and free all the device's information.
+ */
+void
+xf86DeleteInput(InputInfoPtr pInp, int flags)
+{
+ /* First check if the inputdev is valid. */
+ if (pInp == NULL)
+ return;
+
+ if (pInp->module)
+ UnloadModule(pInp->module);
+
+ /* This should *really* be handled in drv->UnInit(dev) call instead, but
+ * if the driver forgets about it make sure we free it or at least crash
+ * with flying colors */
+ free(pInp->private);
+
+ FreeInputAttributes(pInp->attrs);
+
+ /* Remove the entry from the list. */
+ if (pInp == xf86InputDevs)
+ xf86InputDevs = pInp->next;
+ else {
+ InputInfoPtr p = xf86InputDevs;
+ while (p && p->next != pInp)
+ p = p->next;
+ if (p)
+ p->next = pInp->next;
+ /* Else the entry wasn't in the xf86InputDevs list (ignore this). */
+ }
+
+ free(pInp->driver);
+ free(pInp->name);
+ xf86optionListFree(pInp->options);
+ free(pInp);
+}
+
+/*
+ * Apply backend-specific initialization. Invoked after ActiveteDevice(),
+ * i.e. after the driver successfully completed DEVICE_INIT and the device
+ * is advertised.
+ * @param dev the device
+ * @return Success or an error code
+ */
+static int
+xf86InputDevicePostInit(DeviceIntPtr dev) {
+ ApplyAccelerationSettings(dev);
+ return Success;
+}
+
+/**
+ * Create a new input device, activate and enable it.
+ *
+ * Possible return codes:
+ * BadName .. a bad driver name was supplied.
+ * BadImplementation ... The driver does not have a PreInit function. This
+ * is a driver bug.
+ * BadMatch .. device initialization failed.
+ * BadAlloc .. too many input devices
+ *
+ * @param idev The device, already set up with identifier, driver, and the
+ * options.
+ * @param pdev Pointer to the new device, if Success was reported.
+ * @param enable Enable the device after activating it.
+ *
+ * @return Success or an error code
+ */
+_X_INTERNAL int
+xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
+{
+ InputDriverPtr drv = NULL;
+ DeviceIntPtr dev = NULL;
+ int rval;
+
+ /* Memory leak for every attached device if we don't
+ * test if the module is already loaded first */
+ drv = xf86LookupInputDriver(pInfo->driver);
+ if (!drv)
+ if (xf86LoadOneModule(pInfo->driver, NULL))
+ drv = xf86LookupInputDriver(pInfo->driver);
+ if (!drv) {
+ xf86Msg(X_ERROR, "No input driver matching `%s'\n", pInfo->driver);
+ rval = BadName;
+ goto unwind;
+ }
+
+ xf86Msg(X_INFO, "Using input driver '%s' for '%s'\n", drv->driverName, pInfo->name);
+
+ if (!drv->PreInit) {
+ xf86Msg(X_ERROR,
+ "Input driver `%s' has no PreInit function (ignoring)\n",
+ drv->driverName);
+ rval = BadImplementation;
+ goto unwind;
+ }
+
+ xf86AddInput(drv, pInfo);
+
+ rval = drv->PreInit(drv, pInfo, 0);
+
+ if (rval != Success) {
+ xf86Msg(X_ERROR, "PreInit returned %d for \"%s\"\n", rval, pInfo->name);
+ goto unwind;
+ }
+
+ if (!(dev = xf86ActivateDevice(pInfo)))
+ {
+ rval = BadAlloc;
+ goto unwind;
+ }
+
+ rval = ActivateDevice(dev, TRUE);
+ if (rval != Success)
+ {
+ xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name);
+ RemoveDevice(dev, TRUE);
+ goto unwind;
+ }
+
+ rval = xf86InputDevicePostInit(dev);
+ if (rval != Success)
+ {
+ xf86Msg(X_ERROR, "Couldn't post-init device \"%s\"\n", pInfo->name);
+ RemoveDevice(dev, TRUE);
+ goto unwind;
+ }
+
+ /* Enable it if it's properly initialised and we're currently in the VT */
+ if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema)
+ {
+ OsBlockSignals();
+ EnableDevice(dev, TRUE);
+ if (!dev->enabled)
+ {
+ OsReleaseSignals();
+ xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name);
+ rval = BadMatch;
+ goto unwind;
+ }
+ /* send enter/leave event, update sprite window */
+ CheckMotion(NULL, dev);
+ OsReleaseSignals();
+ }
+
+ *pdev = dev;
+ return Success;
+
+unwind:
+ if(pInfo) {
+ if(drv && drv->UnInit)
+ drv->UnInit(drv, pInfo, 0);
+ else
+ xf86DeleteInput(pInfo, 0);
+ }
+ return rval;
+}
+
+int
+NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
+ DeviceIntPtr *pdev)
+{
+ InputInfoPtr pInfo = NULL;
+ InputOption *option = NULL;
+ int rval = Success;
+ int is_auto = 0;
+
+ pInfo = xf86AllocateInput();
+ if (!pInfo)
+ return BadAlloc;
+
+ for (option = options; option; option = option->next) {
+ if (strcasecmp(option->key, "driver") == 0) {
+ if (pInfo->driver) {
+ rval = BadRequest;
+ goto unwind;
+ }
+ pInfo->driver = xstrdup(option->value);
+ if (!pInfo->driver) {
+ rval = BadAlloc;
+ goto unwind;
+ }
+ }
+
+ if (strcasecmp(option->key, "name") == 0 ||
+ strcasecmp(option->key, "identifier") == 0) {
+ if (pInfo->name) {
+ rval = BadRequest;
+ goto unwind;
+ }
+ pInfo->name = xstrdup(option->value);
+ 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)) {
+ is_auto = 1;
+ if (!xf86Info.autoAddDevices) {
+ rval = BadMatch;
+ goto unwind;
+ }
+ }
+ }
+
+ 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;
+ }
+
+ /* Apply InputClass settings */
+ if (attrs) {
+ if (IgnoreInputClass(pInfo, attrs)) {
+ rval = BadIDChoice;
+ goto unwind;
+ }
+
+ rval = MergeInputClasses(pInfo, attrs);
+ if (rval != Success)
+ goto unwind;
+
+ pInfo->attrs = DuplicateInputAttributes(attrs);
+ }
+
+ if (!pInfo->driver || !pInfo->name) {
+ xf86Msg(X_INFO, "No input driver/identifier specified (ignoring)\n");
+ rval = BadRequest;
+ goto unwind;
+ }
+
+ if (!pInfo->name) {
+ xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n");
+ rval = BadMatch;
+ goto unwind;
+ }
+
+ rval = xf86NewInputDevice(pInfo, pdev,
+ (!is_auto || (is_auto && xf86Info.autoEnableDevices)));
+
+ return rval;
+
+unwind:
+ if (is_auto && !xf86Info.autoAddDevices)
+ xf86Msg(X_INFO, "AutoAddDevices is off - not adding device.\n");
+ xf86DeleteInput(pInfo, 0);
+ return rval;
+}
+
+void
+DeleteInputDeviceRequest(DeviceIntPtr pDev)
+{
+ InputInfoPtr pInfo = (InputInfoPtr) pDev->public.devicePrivate;
+ InputDriverPtr drv = NULL;
+ Bool isMaster = IsMaster(pDev);
+
+ if (pInfo) /* need to get these before RemoveDevice */
+ drv = pInfo->drv;
+
+ OsBlockSignals();
+ RemoveDevice(pDev, TRUE);
+
+ if (!isMaster && pInfo != NULL)
+ {
+ if(drv->UnInit)
+ drv->UnInit(drv, pInfo, 0);
+ else
+ xf86DeleteInput(pInfo, 0);
+ }
+ OsReleaseSignals();
+}
+
+/*
+ * convenient functions to post events
+ */
+
+void
+xf86PostMotionEvent(DeviceIntPtr device,
+ int is_absolute,
+ int first_valuator,
+ int num_valuators,
+ ...)
+{
+ va_list var;
+ int i = 0;
+ ValuatorMask mask;
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ valuator_mask_zero(&mask);
+ va_start(var, num_valuators);
+ for (i = 0; i < num_valuators; i++)
+ valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
+ va_end(var);
+
+ xf86PostMotionEventM(device, is_absolute, &mask);
+}
+
+void
+xf86PostMotionEventP(DeviceIntPtr device,
+ int is_absolute,
+ int first_valuator,
+ int num_valuators,
+ const int *valuators)
+{
+ ValuatorMask mask;
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators);
+ xf86PostMotionEventM(device, is_absolute, &mask);
+}
+
+void
+xf86PostMotionEventM(DeviceIntPtr device,
+ int is_absolute,
+ const ValuatorMask *mask)
+{
+ int i = 0, nevents = 0;
+ int flags = 0;
+
+ if (valuator_mask_num_valuators(mask) > 0)
+ {
+ if (is_absolute)
+ flags = POINTER_ABSOLUTE;
+ else
+ flags = POINTER_RELATIVE | POINTER_ACCELERATE;
+ }
+
+#if XFreeXDGA
+ /* The evdev driver may not always send all axes across. */
+ if (valuator_mask_isset(mask, 0) ||
+ valuator_mask_isset(mask, 1))
+ if (miPointerGetScreen(device)) {
+ int index = miPointerGetScreen(device)->myNum;
+ int dx = 0, dy = 0;
+
+ if (valuator_mask_isset(mask, 0))
+ {
+ dx = valuator_mask_get(mask, 0);
+ if (is_absolute)
+ dx -= device->last.valuators[0];
+ }
+
+ if (valuator_mask_isset(mask, 1))
+ {
+ dy = valuator_mask_get(mask, 1);
+ if (is_absolute)
+ dy -= device->last.valuators[1];
+ }
+
+ if (DGAStealMotionEvent(device, index, dx, dy))
+ return;
+ }
+#endif
+
+ nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, flags, mask);
+
+ for (i = 0; i < nevents; i++) {
+ mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+ }
+}
+
+void
+xf86PostProximityEvent(DeviceIntPtr device,
+ int is_in,
+ int first_valuator,
+ int num_valuators,
+ ...)
+{
+ va_list var;
+ int i;
+ ValuatorMask mask;
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ valuator_mask_zero(&mask);
+ va_start(var, num_valuators);
+ for (i = 0; i < num_valuators; i++)
+ valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
+ va_end(var);
+
+ xf86PostProximityEventM(device, is_in, &mask);
+}
+
+void
+xf86PostProximityEventP(DeviceIntPtr device,
+ int is_in,
+ int first_valuator,
+ int num_valuators,
+ const int *valuators)
+{
+ ValuatorMask mask;
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators);
+ xf86PostProximityEventM(device, is_in, &mask);
+}
+
+void
+xf86PostProximityEventM(DeviceIntPtr device,
+ int is_in,
+ const ValuatorMask *mask)
+{
+ int i, nevents;
+
+ nevents = GetProximityEvents(xf86Events, device,
+ is_in ? ProximityIn : ProximityOut, mask);
+ for (i = 0; i < nevents; i++)
+ mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+
+}
+
+void
+xf86PostButtonEvent(DeviceIntPtr device,
+ int is_absolute,
+ int button,
+ int is_down,
+ int first_valuator,
+ int num_valuators,
+ ...)
+{
+ va_list var;
+ ValuatorMask mask;
+ int i = 0;
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ valuator_mask_zero(&mask);
+
+ va_start(var, num_valuators);
+ for (i = 0; i < num_valuators; i++)
+ valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
+ va_end(var);
+
+ xf86PostButtonEventM(device, is_absolute, button, is_down, &mask);
+}
+
+void
+xf86PostButtonEventP(DeviceIntPtr device,
+ int is_absolute,
+ int button,
+ int is_down,
+ int first_valuator,
+ int num_valuators,
+ const int *valuators)
+{
+ ValuatorMask mask;
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators);
+ xf86PostButtonEventM(device, is_absolute, button, is_down, &mask);
+}
+
+void
+xf86PostButtonEventM(DeviceIntPtr device,
+ int is_absolute,
+ int button,
+ int is_down,
+ const ValuatorMask *mask)
+{
+ int i = 0, nevents = 0;
+ int flags = 0;
+
+ if (valuator_mask_num_valuators(mask) > 0)
+ {
+ if (is_absolute)
+ flags = POINTER_ABSOLUTE;
+ else
+ flags = POINTER_RELATIVE | POINTER_ACCELERATE;
+ }
+
+#if XFreeXDGA
+ if (miPointerGetScreen(device)) {
+ int index = miPointerGetScreen(device)->myNum;
+
+ if (DGAStealButtonEvent(device, index, button, is_down))
+ return;
+ }
+#endif
+
+ nevents = GetPointerEvents(xf86Events, device,
+ is_down ? ButtonPress : ButtonRelease, button,
+ flags, mask);
+
+ for (i = 0; i < nevents; i++)
+ mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+
+}
+
+void
+xf86PostKeyEvent(DeviceIntPtr device,
+ unsigned int key_code,
+ int is_down,
+ int is_absolute,
+ int first_valuator,
+ int num_valuators,
+ ...)
+{
+ va_list var;
+ int i = 0;
+ ValuatorMask mask;
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ valuator_mask_zero(&mask);
+
+ va_start(var, num_valuators);
+ for (i = 0; i < num_valuators; i++)
+ valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
+ va_end(var);
+
+ xf86PostKeyEventM(device, key_code, is_down, is_absolute, &mask);
+}
+
+void
+xf86PostKeyEventP(DeviceIntPtr device,
+ unsigned int key_code,
+ int is_down,
+ int is_absolute,
+ int first_valuator,
+ int num_valuators,
+ const int *valuators)
+{
+ ValuatorMask mask;
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators);
+ xf86PostKeyEventM(device, key_code, is_down, is_absolute, &mask);
+}
+
+void
+xf86PostKeyEventM(DeviceIntPtr device,
+ unsigned int key_code,
+ int is_down,
+ int is_absolute,
+ const ValuatorMask *mask)
+{
+ int i = 0, nevents = 0;
+
+#if XFreeXDGA
+ DeviceIntPtr pointer;
+
+ /* Some pointers send key events, paired device is wrong then. */
+ pointer = IsPointerDevice(device) ? device : GetPairedDevice(device);
+ if (miPointerGetScreen(pointer)) {
+ int index = miPointerGetScreen(pointer)->myNum;
+
+ if (DGAStealKeyEvent(device, index, key_code, is_down))
+ return;
+ }
+#endif
+
+ nevents = GetKeyboardEvents(xf86Events, device,
+ is_down ? KeyPress : KeyRelease,
+ key_code, mask);
+
+ for (i = 0; i < nevents; i++)
+ mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+}
+
+void
+xf86PostKeyboardEvent(DeviceIntPtr device,
+ unsigned int key_code,
+ int is_down)
+{
+ ValuatorMask mask;
+
+ valuator_mask_zero(&mask);
+ xf86PostKeyEventM(device, key_code, is_down, 0, &mask);
+}
+
+InputInfoPtr
+xf86FirstLocalDevice(void)
+{
+ return xf86InputDevs;
+}
+
+/*
+ * Cx - raw data from touch screen
+ * to_max - scaled highest dimension
+ * (remember, this is of rows - 1 because of 0 origin)
+ * to_min - scaled lowest dimension
+ * from_max - highest raw value from touch screen calibration
+ * from_min - lowest raw value from touch screen calibration
+ *
+ * This function is the same for X or Y coordinates.
+ * You may have to reverse the high and low values to compensate for
+ * different orgins on the touch screen vs X.
+ *
+ * e.g. to scale from device coordinates into screen coordinates, call
+ * xf86ScaleAxis(x, 0, screen_width, dev_min, dev_max);
+ */
+
+int
+xf86ScaleAxis(int Cx,
+ int to_max,
+ int to_min,
+ int from_max,
+ int from_min )
+{
+ int X;
+ int64_t to_width = to_max - to_min;
+ int64_t from_width = from_max - from_min;
+
+ if (from_width) {
+ X = (int)(((to_width * (Cx - from_min)) / from_width) + to_min);
+ }
+ else {
+ X = 0;
+ ErrorF ("Divide by Zero in xf86ScaleAxis\n");
+ }
+
+ if (X > to_max)
+ X = to_max;
+ if (X < to_min)
+ X = to_min;
+
+ return X;
+}
+
+/*
+ * This function checks the given screen against the current screen and
+ * makes changes if appropriate. It should be called from an XInput driver's
+ * ReadInput function before any events are posted, if the device is screen
+ * specific like a touch screen.
+ */
+void
+xf86XInputSetScreen(InputInfoPtr pInfo,
+ int screen_number,
+ int x,
+ int y)
+{
+ if (miPointerGetScreen(pInfo->dev) !=
+ screenInfo.screens[screen_number]) {
+ miPointerSetScreen(pInfo->dev, screen_number, x, y);
+ }
+}
+
+
+void
+xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
+ int resolution, int min_res, int max_res, int mode)
+{
+ if (!dev || !dev->valuator)
+ return;
+
+ InitValuatorAxisStruct(dev, axnum, label, minval, maxval, resolution, min_res,
+ max_res, mode);
+}
+
+/*
+ * Set the valuator values to be in synch with dix/event.c
+ * DefineInitialRootWindow().
+ */
+void
+xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
+{
+ if (axnum == 0) {
+ dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
+ dev->last.valuators[0] = dev->valuator->axisVal[0];
+ }
+ else if (axnum == 1) {
+ dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
+ dev->last.valuators[1] = dev->valuator->axisVal[1];
+ }
+}
+
+
+/**
+ * Deactivate a device. Call this function from the driver if you receive a
+ * read error or something else that spoils your day.
+ * Device will be moved to the off_devices list, but it will still be there
+ * until you really clean up after it.
+ * Notifies the client about an inactive device.
+ *
+ * @param panic True if device is unrecoverable and needs to be removed.
+ */
+void
+xf86DisableDevice(DeviceIntPtr dev, Bool panic)
+{
+ if(!panic)
+ {
+ DisableDevice(dev, TRUE);
+ } else
+ {
+ SendDevicePresenceEvent(dev->id, DeviceUnrecoverable);
+ DeleteInputDeviceRequest(dev);
+ }
+}
+
+/**
+ * Reactivate a device. Call this function from the driver if you just found
+ * out that the read error wasn't quite that bad after all.
+ * Device will be re-activated, and an event sent to the client.
+ */
+void
+xf86EnableDevice(DeviceIntPtr dev)
+{
+ EnableDevice(dev, TRUE);
+}
+
+/* end of xf86Xinput.c */
diff --git a/xorg-server/hw/xfree86/common/xf86sbusBus.c b/xorg-server/hw/xfree86/common/xf86sbusBus.c
index 181c6ab00..6e6ab948f 100644
--- a/xorg-server/hw/xfree86/common/xf86sbusBus.c
+++ b/xorg-server/hw/xfree86/common/xf86sbusBus.c
@@ -1,714 +1,714 @@
-/*
- * SBUS bus-specific code.
- *
- * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * 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
- * JAKUB JELINEK 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_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <X11/X.h>
-#include "os.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#include "xf86cmap.h"
-
-#include "xf86Bus.h"
-
-#include "xf86sbusBus.h"
-#include "xf86Sbus.h"
-
-Bool sbusSlotClaimed = FALSE;
-
-static int xf86nSbusInfo;
-
-static void
-CheckSbusDevice(const char *device, int fbNum)
-{
- int fd, i;
- struct fbgattr fbattr;
- sbusDevicePtr psdp;
-
- fd = open(device, O_RDONLY, 0);
- if (fd < 0)
- return;
- memset(&fbattr, 0, sizeof(fbattr));
- if (ioctl(fd, FBIOGATTR, &fbattr) < 0) {
- if (ioctl(fd, FBIOGTYPE, &fbattr.fbtype) < 0) {
- close(fd);
- return;
- }
- }
- close(fd);
- for (i = 0; sbusDeviceTable[i].devId; i++)
- if (sbusDeviceTable[i].fbType == fbattr.fbtype.fb_type)
- break;
- if (! sbusDeviceTable[i].devId)
- return;
- xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (++xf86nSbusInfo + 1));
- xf86SbusInfo[xf86nSbusInfo] = NULL;
- xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof (sbusDevice), 1);
- psdp->devId = sbusDeviceTable[i].devId;
- psdp->fbNum = fbNum;
- psdp->device = xnfstrdup(device);
- psdp->width = fbattr.fbtype.fb_width;
- psdp->height = fbattr.fbtype.fb_height;
- psdp->fd = -1;
-}
-
-void
-xf86SbusProbe(void)
-{
- int i, useProm = 0;
- char fbDevName[32];
- sbusDevicePtr psdp, *psdpp;
-
- xf86SbusInfo = malloc(sizeof(psdp));
- *xf86SbusInfo = NULL;
- for (i = 0; i < 32; i++) {
- sprintf(fbDevName, "/dev/fb%d", i);
- CheckSbusDevice(fbDevName, i);
- }
- if (sparcPromInit() >= 0) {
- useProm = 1;
- sparcPromAssignNodes();
- }
- for (psdpp = xf86SbusInfo; (psdp = *psdpp); psdpp++) {
- for (i = 0; sbusDeviceTable[i].devId; i++)
- if (sbusDeviceTable[i].devId == psdp->devId)
- psdp->descr = sbusDeviceTable[i].descr;
- /*
- * If we can use PROM information and found the PROM node for this
- * device, we can tell more about the card.
- */
- if (useProm && psdp->node.node) {
- char *prop, *promPath;
- int len, chiprev, vmsize;
-
- switch (psdp->devId) {
- case SBUS_DEVICE_MGX:
- prop = sparcPromGetProperty(&psdp->node, "fb_size", &len);
- if (prop && len == 4 && *(int *)prop == 0x400000)
- psdp->descr = "Quantum 3D MGXplus with 4M VRAM";
- break;
- case SBUS_DEVICE_CG6:
- chiprev = 0;
- vmsize = 0;
- prop = sparcPromGetProperty(&psdp->node, "chiprev", &len);
- if (prop && len == 4)
- chiprev = *(int *)prop;
- prop = sparcPromGetProperty(&psdp->node, "vmsize", &len);
- if (prop && len == 4)
- vmsize = *(int *)prop;
- switch (chiprev) {
- case 1:
- case 2:
- case 3:
- case 4:
- psdp->descr = "Sun Double width GX"; break;
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- psdp->descr = "Sun Single width GX"; break;
- case 11:
- switch (vmsize) {
- case 2:
- psdp->descr = "Sun Turbo GX with 1M VSIMM"; break;
- case 4:
- psdp->descr = "Sun Turbo GX Plus"; break;
- default:
- psdp->descr = "Sun Turbo GX"; break;
- }
- }
- break;
- case SBUS_DEVICE_CG14:
- prop = sparcPromGetProperty(&psdp->node, "reg", &len);
- vmsize = 0;
- if (prop && !(len % 12) && len > 0)
- vmsize = *(int *)(prop + len - 4);
- switch (vmsize) {
- case 0x400000:
- psdp->descr = "Sun SX with 4M VSIMM"; break;
- case 0x800000:
- psdp->descr = "Sun SX with 8M VSIMM"; break;
- }
- break;
- case SBUS_DEVICE_LEO:
- prop = sparcPromGetProperty(&psdp->node, "model", &len);
- if (prop && len > 0 && !strstr(prop, "501-2503"))
- psdp->descr = "Sun Turbo ZX";
- break;
- case SBUS_DEVICE_TCX:
- if (sparcPromGetBool(&psdp->node, "tcx-8-bit"))
- psdp->descr = "Sun TCX (8bit)";
- else
- psdp->descr = "Sun TCX (S24)";
- break;
- case SBUS_DEVICE_FFB:
- prop = sparcPromGetProperty(&psdp->node, "name", &len);
- chiprev = 0;
- prop = sparcPromGetProperty(&psdp->node, "board_type", &len);
- if (prop && len == 4)
- chiprev = *(int *)prop;
- if (strstr (prop, "afb")) {
- if (chiprev == 3)
- psdp->descr = "Sun|Elite3D-M6 Horizontal";
- } else {
- switch (chiprev) {
- case 0x08:
- psdp->descr = "Sun FFB 67MHz Creator"; break;
- case 0x0b:
- psdp->descr = "Sun FFB 67MHz Creator 3D"; break;
- case 0x1b:
- psdp->descr = "Sun FFB 75MHz Creator 3D"; break;
- case 0x20:
- case 0x28:
- psdp->descr = "Sun FFB2 Vertical Creator"; break;
- case 0x23:
- case 0x2b:
- psdp->descr = "Sun FFB2 Vertical Creator 3D"; break;
- case 0x30:
- psdp->descr = "Sun FFB2+ Vertical Creator"; break;
- case 0x33:
- psdp->descr = "Sun FFB2+ Vertical Creator 3D"; break;
- case 0x40:
- case 0x48:
- psdp->descr = "Sun FFB2 Horizontal Creator"; break;
- case 0x43:
- case 0x4b:
- psdp->descr = "Sun FFB2 Horizontal Creator 3D"; break;
- }
- }
- break;
- }
-
- xf86Msg(X_PROBED, "SBUS:(0x%08x) %s", psdp->node.node, psdp->descr);
- promPath = sparcPromNode2Pathname (&psdp->node);
- if (promPath) {
- xf86ErrorF(" at %s", promPath);
- free(promPath);
- }
- } else
- xf86Msg(X_PROBED, "SBUS: %s", psdp->descr);
- xf86ErrorF("\n");
- }
- if (useProm)
- sparcPromClose();
-}
-
-/*
- * Parse a BUS ID string, and return the SBUS bus parameters if it was
- * in the correct format for a SBUS bus id.
- */
-
-Bool
-xf86ParseSbusBusString(const char *busID, int *fbNum)
-{
- /*
- * The format is assumed to be one of:
- * "fbN", e.g. "fb1", which means the device corresponding to /dev/fbN
- * "nameN", e.g. "cgsix0", which means Nth instance of card NAME
- * "/prompath", e.g. "/sbus@0,10001000/cgsix@3,0" which is PROM pathname
- * to the device.
- */
-
- const char *id;
- int i, len;
-
- if (StringToBusType(busID, &id) != BUS_SBUS)
- return FALSE;
-
- if (*id != '/') {
- if (!strncmp (id, "fb", 2)) {
- if (!isdigit(id[2]))
- return FALSE;
- *fbNum = atoi(id + 2);
- return TRUE;
- } else {
- sbusDevicePtr *psdpp;
- int devId;
-
- for (i = 0, len = 0; sbusDeviceTable[i].devId; i++) {
- len = strlen(sbusDeviceTable[i].promName);
- if (!strncmp (sbusDeviceTable[i].promName, id, len)
- && isdigit(id[len]))
- break;
- }
- devId = sbusDeviceTable[i].devId;
- if (!devId) return FALSE;
- i = atoi(id + len);
- for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
- if ((*psdpp)->devId != devId)
- continue;
- if (!i) {
- *fbNum = (*psdpp)->fbNum;
- return TRUE;
- }
- i--;
- }
- }
- return FALSE;
- }
-
- if (sparcPromInit() >= 0) {
- i = sparcPromPathname2Node(id);
- sparcPromClose();
- if (i) {
- sbusDevicePtr *psdpp;
- for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
- if ((*psdpp)->node.node == i) {
- *fbNum = (*psdpp)->fbNum;
- return TRUE;
- }
- }
- }
- }
- return FALSE;
-}
-
-/*
- * Compare a BUS ID string with a SBUS bus id. Return TRUE if they match.
- */
-
-Bool
-xf86CompareSbusBusString(const char *busID, int fbNum)
-{
- int iFbNum;
-
- if (xf86ParseSbusBusString(busID, &iFbNum)) {
- return fbNum == iFbNum;
- } else {
- return FALSE;
- }
-}
-
-/*
- * Check if the slot requested is free. If it is already in use, return FALSE.
- */
-
-Bool
-xf86CheckSbusSlot(int fbNum)
-{
- int i;
- EntityPtr p;
-
- for (i = 0; i < xf86NumEntities; i++) {
- p = xf86Entities[i];
- /* Check if this SBUS slot is taken */
- if (p->bus.type == BUS_SBUS && p->bus.id.sbus.fbNum == fbNum)
- return FALSE;
- }
-
- return TRUE;
-}
-
-/*
- * If the slot requested is already in use, return -1.
- * Otherwise, claim the slot for the screen requesting it.
- */
-
-int
-xf86ClaimSbusSlot(sbusDevicePtr psdp, DriverPtr drvp,
- GDevPtr dev, Bool active)
-{
- EntityPtr p = NULL;
-
- int num;
-
- if (xf86CheckSbusSlot(psdp->fbNum)) {
- num = xf86AllocateEntity();
- p = xf86Entities[num];
- p->driver = drvp;
- p->chipset = -1;
- p->bus.type = BUS_SBUS;
- xf86AddDevToEntity(num, dev);
- p->bus.id.sbus.fbNum = psdp->fbNum;
- p->active = active;
- p->inUse = FALSE;
- sbusSlotClaimed = TRUE;
- return num;
- } else
- return -1;
-}
-
-int
-xf86MatchSbusInstances(const char *driverName, int sbusDevId,
- GDevPtr *devList, int numDevs, DriverPtr drvp,
- int **foundEntities)
-{
- int i,j;
- sbusDevicePtr psdp, *psdpp;
- int numClaimedInstances = 0;
- int allocatedInstances = 0;
- int numFound = 0;
- GDevPtr devBus = NULL;
- GDevPtr dev = NULL;
- int *retEntities = NULL;
- int useProm = 0;
-
- struct Inst {
- sbusDevicePtr sbus;
- GDevPtr dev;
- Bool claimed; /* BusID matches with a device section */
- } *instances = NULL;
-
- *foundEntities = NULL;
- for (psdpp = xf86SbusInfo, psdp = *psdpp; psdp; psdp = *++psdpp) {
- if (psdp->devId != sbusDevId)
- continue;
- if (psdp->fd == -2)
- continue;
- ++allocatedInstances;
- instances = xnfrealloc(instances,
- allocatedInstances * sizeof(struct Inst));
- instances[allocatedInstances - 1].sbus = psdp;
- instances[allocatedInstances - 1].dev = NULL;
- instances[allocatedInstances - 1].claimed = FALSE;
- numFound++;
- }
-
- /*
- * This may be debatable, but if no SBUS devices with a matching vendor
- * type is found, return zero now. It is probably not desirable to
- * allow the config file to override this.
- */
- if (allocatedInstances <= 0) {
- free(instances);
- return 0;
- }
-
- if (sparcPromInit() >= 0)
- useProm = 1;
-
- if (xf86DoConfigure && xf86DoConfigurePass1) {
- GDevPtr pGDev;
- int actualcards = 0;
- for (i = 0; i < allocatedInstances; i++) {
- actualcards++;
- pGDev = xf86AddBusDeviceToConfigure(drvp->driverName, BUS_SBUS,
- instances[i].sbus, -1);
- if (pGDev) {
- /*
- * XF86Match???Instances() treat chipID and chipRev as
- * overrides, so clobber them here.
- */
- pGDev->chipID = pGDev->chipRev = -1;
- }
- }
- free(instances);
- if (useProm)
- sparcPromClose();
- return actualcards;
- }
-
- DebugF("%s instances found: %d\n", driverName, allocatedInstances);
-
- for (i = 0; i < allocatedInstances; i++) {
- char *promPath = NULL;
-
- psdp = instances[i].sbus;
- devBus = NULL;
- dev = NULL;
- if (useProm && psdp->node.node)
- promPath = sparcPromNode2Pathname(&psdp->node);
-
- for (j = 0; j < numDevs; j++) {
- if (devList[j]->busID && *devList[j]->busID) {
- if (xf86CompareSbusBusString(devList[j]->busID, psdp->fbNum)) {
- if (devBus)
- xf86MsgVerb(X_WARNING,0,
- "%s: More than one matching Device section for "
- "instance (BusID: %s) found: %s\n",
- driverName,devList[j]->identifier,
- devList[j]->busID);
- else
- devBus = devList[j];
- }
- } else {
- if (!dev && !devBus) {
- if (promPath)
- xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:%s\n",
- promPath);
- else
- xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:fb%d\n",
- psdp->fbNum);
- dev = devList[j];
- } else
- xf86MsgVerb(X_WARNING, 0,
- "%s: More than one matching Device section "
- "found: %s\n", driverName, devList[j]->identifier);
- }
- }
- if (devBus) dev = devBus; /* busID preferred */
- if (!dev && psdp->fd != -2) {
- if (promPath) {
- xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
- "for instance (BusID SBUS:%s) found\n",
- driverName, promPath);
- } else
- xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
- "for instance (BusID SBUS:fb%d) found\n",
- driverName, psdp->fbNum);
- } else if (dev) {
- numClaimedInstances++;
- instances[i].claimed = TRUE;
- instances[i].dev = dev;
- }
- free(promPath);
- }
-
- DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
-
- /*
- * Of the claimed instances, check that another driver hasn't already
- * claimed its slot.
- */
- numFound = 0;
- for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
- if (!instances[i].claimed)
- continue;
- psdp = instances[i].sbus;
- if (!xf86CheckSbusSlot(psdp->fbNum))
- continue;
-
- DebugF("%s: card at fb%d %08x is claimed by a Device section\n",
- driverName, psdp->fbNum, psdp->node.node);
-
- /* Allocate an entry in the lists to be returned */
- numFound++;
- retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
- retEntities[numFound - 1]
- = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev,instances[i].dev->active ?
- TRUE : FALSE);
- }
- free(instances);
- if (numFound > 0) {
- *foundEntities = retEntities;
- }
-
- if (useProm)
- sparcPromClose();
-
- return numFound;
-}
-
-/*
- * xf86GetSbusInfoForEntity() -- Get the sbusDevicePtr of entity.
- */
-sbusDevicePtr
-xf86GetSbusInfoForEntity(int entityIndex)
-{
- sbusDevicePtr *psdpp;
- EntityPtr p = xf86Entities[entityIndex];
-
- if (entityIndex >= xf86NumEntities
- || p->bus.type != BUS_SBUS) return NULL;
-
- for (psdpp = xf86SbusInfo; *psdpp != NULL; psdpp++) {
- if (p->bus.id.sbus.fbNum == (*psdpp)->fbNum)
- return *psdpp;
- }
- return NULL;
-}
-
-int
-xf86GetEntityForSbusInfo(sbusDevicePtr psdp)
-{
- int i;
-
- for (i = 0; i < xf86NumEntities; i++) {
- EntityPtr p = xf86Entities[i];
- if (p->bus.type != BUS_SBUS) continue;
-
- if (p->bus.id.sbus.fbNum == psdp->fbNum)
- return i;
- }
- return -1;
-}
-
-void
-xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn, sbusDevicePtr psdp)
-{
- DisplayModePtr mode;
-
- mode = xnfcalloc(sizeof(DisplayModeRec), 1);
- mode->name = "current";
- mode->next = mode;
- mode->prev = mode;
- mode->type = M_T_BUILTIN;
- mode->Clock = 100000000;
- mode->HDisplay = psdp->width;
- mode->HSyncStart = psdp->width;
- mode->HSyncEnd = psdp->width;
- mode->HTotal = psdp->width;
- mode->VDisplay = psdp->height;
- mode->VSyncStart = psdp->height;
- mode->VSyncEnd = psdp->height;
- mode->VTotal = psdp->height;
- mode->SynthClock = mode->Clock;
- mode->CrtcHDisplay = mode->HDisplay;
- mode->CrtcHSyncStart = mode->HSyncStart;
- mode->CrtcHSyncEnd = mode->HSyncEnd;
- mode->CrtcHTotal = mode->HTotal;
- mode->CrtcVDisplay = mode->VDisplay;
- mode->CrtcVSyncStart = mode->VSyncStart;
- mode->CrtcVSyncEnd = mode->VSyncEnd;
- mode->CrtcVTotal = mode->VTotal;
- mode->CrtcHAdjusted = FALSE;
- mode->CrtcVAdjusted = FALSE;
- pScrn->modes = mode;
- pScrn->virtualX = psdp->width;
- pScrn->virtualY = psdp->height;
-}
-
-static sbusPaletteKeyIndex;
-static DevPrivateKey sbusPaletteKey = &sbusPaletteKeyIndex;
-typedef struct _sbusCmap {
- sbusDevicePtr psdp;
- CloseScreenProcPtr CloseScreen;
- Bool origCmapValid;
- unsigned char origRed[16];
- unsigned char origGreen[16];
- unsigned char origBlue[16];
-} sbusCmapRec, *sbusCmapPtr;
-
-#define SBUSCMAPPTR(pScreen) ((sbusCmapPtr) \
- dixLookupPrivate(&(pScreen)->devPrivates, sbusPaletteKey))
-
-static void
-xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
- LOCO *colors, VisualPtr pVisual)
-{
- int i, index;
- sbusCmapPtr cmap;
- struct fbcmap fbcmap;
- unsigned char *data = malloc(numColors*3);
-
- cmap = SBUSCMAPPTR(pScrn->pScreen);
- if (!cmap) return;
- fbcmap.count = 0;
- fbcmap.index = indices[0];
- fbcmap.red = data;
- fbcmap.green = data + numColors;
- fbcmap.blue = fbcmap.green + numColors;
- for (i = 0; i < numColors; i++) {
- index = indices[i];
- if (fbcmap.count && index != fbcmap.index + fbcmap.count) {
- ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
- fbcmap.count = 0;
- fbcmap.index = index;
- }
- fbcmap.red[fbcmap.count] = colors[index].red;
- fbcmap.green[fbcmap.count] = colors[index].green;
- fbcmap.blue[fbcmap.count++] = colors[index].blue;
- }
- ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
- free(data);
-}
-
-static Bool
-xf86SbusCmapCloseScreen(int i, ScreenPtr pScreen)
-{
- sbusCmapPtr cmap;
- struct fbcmap fbcmap;
-
- cmap = SBUSCMAPPTR(pScreen);
- if (cmap->origCmapValid) {
- fbcmap.index = 0;
- fbcmap.count = 16;
- fbcmap.red = cmap->origRed;
- fbcmap.green = cmap->origGreen;
- fbcmap.blue = cmap->origBlue;
- ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
- }
- pScreen->CloseScreen = cmap->CloseScreen;
- free(cmap);
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-Bool
-xf86SbusHandleColormaps(ScreenPtr pScreen, sbusDevicePtr psdp)
-{
- sbusCmapPtr cmap;
- struct fbcmap fbcmap;
- unsigned char data[2];
-
- cmap = xnfcalloc(1, sizeof(sbusCmapRec));
- dixSetPrivate(&pScreen->devPrivates, sbusPaletteKey, cmap);
- cmap->psdp = psdp;
- fbcmap.index = 0;
- fbcmap.count = 16;
- fbcmap.red = cmap->origRed;
- fbcmap.green = cmap->origGreen;
- fbcmap.blue = cmap->origBlue;
- if (ioctl (psdp->fd, FBIOGETCMAP, &fbcmap) >= 0)
- cmap->origCmapValid = TRUE;
- fbcmap.index = 0;
- fbcmap.count = 2;
- fbcmap.red = data;
- fbcmap.green = data;
- fbcmap.blue = data;
- if (pScreen->whitePixel == 0) {
- data[0] = 255;
- data[1] = 0;
- } else {
- data[0] = 0;
- data[1] = 255;
- }
- ioctl (psdp->fd, FBIOPUTCMAP, &fbcmap);
- cmap->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xf86SbusCmapCloseScreen;
- return xf86HandleColormaps(pScreen, 256, 8,
- xf86SbusCmapLoadPalette, NULL, 0);
-}
-
-Bool
-xf86SbusConfigure(void *busData, sbusDevicePtr sBus)
-{
- if (sBus && sBus->fbNum == ((sbusDevicePtr) busData)->fbNum)
- return 0;
- return 1;
-}
-
-void
-xf86SbusConfigureNewDev(void *busData, sbusDevicePtr sBus, GDevRec *GDev)
-{
- char *promPath = NULL;
-
- sBus = (sbusDevicePtr) busData;
- GDev->identifier = sBus->descr;
- if (sparcPromInit() >= 0) {
- promPath = sparcPromNode2Pathname(&sBus->node);
- sparcPromClose();
- }
- if (promPath) {
- XNFasprintf(&GDev->busID, "SBUS:%s", promPath);
- free(promPath);
- } else {
- XNFasprintf(&GDev->busID, "SBUS:fb%d", sBus->fbNum);
- }
-}
+/*
+ * SBUS bus-specific code.
+ *
+ * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * 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
+ * JAKUB JELINEK 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_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <X11/X.h>
+#include "os.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86cmap.h"
+
+#include "xf86Bus.h"
+
+#include "xf86sbusBus.h"
+#include "xf86Sbus.h"
+
+Bool sbusSlotClaimed = FALSE;
+
+static int xf86nSbusInfo;
+
+static void
+CheckSbusDevice(const char *device, int fbNum)
+{
+ int fd, i;
+ struct fbgattr fbattr;
+ sbusDevicePtr psdp;
+
+ fd = open(device, O_RDONLY, 0);
+ if (fd < 0)
+ return;
+ memset(&fbattr, 0, sizeof(fbattr));
+ if (ioctl(fd, FBIOGATTR, &fbattr) < 0) {
+ if (ioctl(fd, FBIOGTYPE, &fbattr.fbtype) < 0) {
+ close(fd);
+ return;
+ }
+ }
+ close(fd);
+ for (i = 0; sbusDeviceTable[i].devId; i++)
+ if (sbusDeviceTable[i].fbType == fbattr.fbtype.fb_type)
+ break;
+ if (! sbusDeviceTable[i].devId)
+ return;
+ xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (++xf86nSbusInfo + 1));
+ xf86SbusInfo[xf86nSbusInfo] = NULL;
+ xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof (sbusDevice), 1);
+ psdp->devId = sbusDeviceTable[i].devId;
+ psdp->fbNum = fbNum;
+ psdp->device = xnfstrdup(device);
+ psdp->width = fbattr.fbtype.fb_width;
+ psdp->height = fbattr.fbtype.fb_height;
+ psdp->fd = -1;
+}
+
+void
+xf86SbusProbe(void)
+{
+ int i, useProm = 0;
+ char fbDevName[32];
+ sbusDevicePtr psdp, *psdpp;
+
+ xf86SbusInfo = malloc(sizeof(psdp));
+ *xf86SbusInfo = NULL;
+ for (i = 0; i < 32; i++) {
+ sprintf(fbDevName, "/dev/fb%d", i);
+ CheckSbusDevice(fbDevName, i);
+ }
+ if (sparcPromInit() >= 0) {
+ useProm = 1;
+ sparcPromAssignNodes();
+ }
+ for (psdpp = xf86SbusInfo; (psdp = *psdpp); psdpp++) {
+ for (i = 0; sbusDeviceTable[i].devId; i++)
+ if (sbusDeviceTable[i].devId == psdp->devId)
+ psdp->descr = sbusDeviceTable[i].descr;
+ /*
+ * If we can use PROM information and found the PROM node for this
+ * device, we can tell more about the card.
+ */
+ if (useProm && psdp->node.node) {
+ char *prop, *promPath;
+ int len, chiprev, vmsize;
+
+ switch (psdp->devId) {
+ case SBUS_DEVICE_MGX:
+ prop = sparcPromGetProperty(&psdp->node, "fb_size", &len);
+ if (prop && len == 4 && *(int *)prop == 0x400000)
+ psdp->descr = "Quantum 3D MGXplus with 4M VRAM";
+ break;
+ case SBUS_DEVICE_CG6:
+ chiprev = 0;
+ vmsize = 0;
+ prop = sparcPromGetProperty(&psdp->node, "chiprev", &len);
+ if (prop && len == 4)
+ chiprev = *(int *)prop;
+ prop = sparcPromGetProperty(&psdp->node, "vmsize", &len);
+ if (prop && len == 4)
+ vmsize = *(int *)prop;
+ switch (chiprev) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ psdp->descr = "Sun Double width GX"; break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ psdp->descr = "Sun Single width GX"; break;
+ case 11:
+ switch (vmsize) {
+ case 2:
+ psdp->descr = "Sun Turbo GX with 1M VSIMM"; break;
+ case 4:
+ psdp->descr = "Sun Turbo GX Plus"; break;
+ default:
+ psdp->descr = "Sun Turbo GX"; break;
+ }
+ }
+ break;
+ case SBUS_DEVICE_CG14:
+ prop = sparcPromGetProperty(&psdp->node, "reg", &len);
+ vmsize = 0;
+ if (prop && !(len % 12) && len > 0)
+ vmsize = *(int *)(prop + len - 4);
+ switch (vmsize) {
+ case 0x400000:
+ psdp->descr = "Sun SX with 4M VSIMM"; break;
+ case 0x800000:
+ psdp->descr = "Sun SX with 8M VSIMM"; break;
+ }
+ break;
+ case SBUS_DEVICE_LEO:
+ prop = sparcPromGetProperty(&psdp->node, "model", &len);
+ if (prop && len > 0 && !strstr(prop, "501-2503"))
+ psdp->descr = "Sun Turbo ZX";
+ break;
+ case SBUS_DEVICE_TCX:
+ if (sparcPromGetBool(&psdp->node, "tcx-8-bit"))
+ psdp->descr = "Sun TCX (8bit)";
+ else
+ psdp->descr = "Sun TCX (S24)";
+ break;
+ case SBUS_DEVICE_FFB:
+ prop = sparcPromGetProperty(&psdp->node, "name", &len);
+ chiprev = 0;
+ prop = sparcPromGetProperty(&psdp->node, "board_type", &len);
+ if (prop && len == 4)
+ chiprev = *(int *)prop;
+ if (strstr (prop, "afb")) {
+ if (chiprev == 3)
+ psdp->descr = "Sun|Elite3D-M6 Horizontal";
+ } else {
+ switch (chiprev) {
+ case 0x08:
+ psdp->descr = "Sun FFB 67MHz Creator"; break;
+ case 0x0b:
+ psdp->descr = "Sun FFB 67MHz Creator 3D"; break;
+ case 0x1b:
+ psdp->descr = "Sun FFB 75MHz Creator 3D"; break;
+ case 0x20:
+ case 0x28:
+ psdp->descr = "Sun FFB2 Vertical Creator"; break;
+ case 0x23:
+ case 0x2b:
+ psdp->descr = "Sun FFB2 Vertical Creator 3D"; break;
+ case 0x30:
+ psdp->descr = "Sun FFB2+ Vertical Creator"; break;
+ case 0x33:
+ psdp->descr = "Sun FFB2+ Vertical Creator 3D"; break;
+ case 0x40:
+ case 0x48:
+ psdp->descr = "Sun FFB2 Horizontal Creator"; break;
+ case 0x43:
+ case 0x4b:
+ psdp->descr = "Sun FFB2 Horizontal Creator 3D"; break;
+ }
+ }
+ break;
+ }
+
+ xf86Msg(X_PROBED, "SBUS:(0x%08x) %s", psdp->node.node, psdp->descr);
+ promPath = sparcPromNode2Pathname (&psdp->node);
+ if (promPath) {
+ xf86ErrorF(" at %s", promPath);
+ free(promPath);
+ }
+ } else
+ xf86Msg(X_PROBED, "SBUS: %s", psdp->descr);
+ xf86ErrorF("\n");
+ }
+ if (useProm)
+ sparcPromClose();
+}
+
+/*
+ * Parse a BUS ID string, and return the SBUS bus parameters if it was
+ * in the correct format for a SBUS bus id.
+ */
+
+Bool
+xf86ParseSbusBusString(const char *busID, int *fbNum)
+{
+ /*
+ * The format is assumed to be one of:
+ * "fbN", e.g. "fb1", which means the device corresponding to /dev/fbN
+ * "nameN", e.g. "cgsix0", which means Nth instance of card NAME
+ * "/prompath", e.g. "/sbus@0,10001000/cgsix@3,0" which is PROM pathname
+ * to the device.
+ */
+
+ const char *id;
+ int i, len;
+
+ if (StringToBusType(busID, &id) != BUS_SBUS)
+ return FALSE;
+
+ if (*id != '/') {
+ if (!strncmp (id, "fb", 2)) {
+ if (!isdigit(id[2]))
+ return FALSE;
+ *fbNum = atoi(id + 2);
+ return TRUE;
+ } else {
+ sbusDevicePtr *psdpp;
+ int devId;
+
+ for (i = 0, len = 0; sbusDeviceTable[i].devId; i++) {
+ len = strlen(sbusDeviceTable[i].promName);
+ if (!strncmp (sbusDeviceTable[i].promName, id, len)
+ && isdigit(id[len]))
+ break;
+ }
+ devId = sbusDeviceTable[i].devId;
+ if (!devId) return FALSE;
+ i = atoi(id + len);
+ for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
+ if ((*psdpp)->devId != devId)
+ continue;
+ if (!i) {
+ *fbNum = (*psdpp)->fbNum;
+ return TRUE;
+ }
+ i--;
+ }
+ }
+ return FALSE;
+ }
+
+ if (sparcPromInit() >= 0) {
+ i = sparcPromPathname2Node(id);
+ sparcPromClose();
+ if (i) {
+ sbusDevicePtr *psdpp;
+ for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
+ if ((*psdpp)->node.node == i) {
+ *fbNum = (*psdpp)->fbNum;
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Compare a BUS ID string with a SBUS bus id. Return TRUE if they match.
+ */
+
+Bool
+xf86CompareSbusBusString(const char *busID, int fbNum)
+{
+ int iFbNum;
+
+ if (xf86ParseSbusBusString(busID, &iFbNum)) {
+ return fbNum == iFbNum;
+ } else {
+ return FALSE;
+ }
+}
+
+/*
+ * Check if the slot requested is free. If it is already in use, return FALSE.
+ */
+
+Bool
+xf86CheckSbusSlot(int fbNum)
+{
+ int i;
+ EntityPtr p;
+
+ for (i = 0; i < xf86NumEntities; i++) {
+ p = xf86Entities[i];
+ /* Check if this SBUS slot is taken */
+ if (p->bus.type == BUS_SBUS && p->bus.id.sbus.fbNum == fbNum)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * If the slot requested is already in use, return -1.
+ * Otherwise, claim the slot for the screen requesting it.
+ */
+
+int
+xf86ClaimSbusSlot(sbusDevicePtr psdp, DriverPtr drvp,
+ GDevPtr dev, Bool active)
+{
+ EntityPtr p = NULL;
+
+ int num;
+
+ if (xf86CheckSbusSlot(psdp->fbNum)) {
+ num = xf86AllocateEntity();
+ p = xf86Entities[num];
+ p->driver = drvp;
+ p->chipset = -1;
+ p->bus.type = BUS_SBUS;
+ xf86AddDevToEntity(num, dev);
+ p->bus.id.sbus.fbNum = psdp->fbNum;
+ p->active = active;
+ p->inUse = FALSE;
+ sbusSlotClaimed = TRUE;
+ return num;
+ } else
+ return -1;
+}
+
+int
+xf86MatchSbusInstances(const char *driverName, int sbusDevId,
+ GDevPtr *devList, int numDevs, DriverPtr drvp,
+ int **foundEntities)
+{
+ int i,j;
+ sbusDevicePtr psdp, *psdpp;
+ int numClaimedInstances = 0;
+ int allocatedInstances = 0;
+ int numFound = 0;
+ GDevPtr devBus = NULL;
+ GDevPtr dev = NULL;
+ int *retEntities = NULL;
+ int useProm = 0;
+
+ struct Inst {
+ sbusDevicePtr sbus;
+ GDevPtr dev;
+ Bool claimed; /* BusID matches with a device section */
+ } *instances = NULL;
+
+ *foundEntities = NULL;
+ for (psdpp = xf86SbusInfo, psdp = *psdpp; psdp; psdp = *++psdpp) {
+ if (psdp->devId != sbusDevId)
+ continue;
+ if (psdp->fd == -2)
+ continue;
+ ++allocatedInstances;
+ instances = xnfrealloc(instances,
+ allocatedInstances * sizeof(struct Inst));
+ instances[allocatedInstances - 1].sbus = psdp;
+ instances[allocatedInstances - 1].dev = NULL;
+ instances[allocatedInstances - 1].claimed = FALSE;
+ numFound++;
+ }
+
+ /*
+ * This may be debatable, but if no SBUS devices with a matching vendor
+ * type is found, return zero now. It is probably not desirable to
+ * allow the config file to override this.
+ */
+ if (allocatedInstances <= 0) {
+ free(instances);
+ return 0;
+ }
+
+ if (sparcPromInit() >= 0)
+ useProm = 1;
+
+ if (xf86DoConfigure && xf86DoConfigurePass1) {
+ GDevPtr pGDev;
+ int actualcards = 0;
+ for (i = 0; i < allocatedInstances; i++) {
+ actualcards++;
+ pGDev = xf86AddBusDeviceToConfigure(drvp->driverName, BUS_SBUS,
+ instances[i].sbus, -1);
+ if (pGDev) {
+ /*
+ * XF86Match???Instances() treat chipID and chipRev as
+ * overrides, so clobber them here.
+ */
+ pGDev->chipID = pGDev->chipRev = -1;
+ }
+ }
+ free(instances);
+ if (useProm)
+ sparcPromClose();
+ return actualcards;
+ }
+
+ DebugF("%s instances found: %d\n", driverName, allocatedInstances);
+
+ for (i = 0; i < allocatedInstances; i++) {
+ char *promPath = NULL;
+
+ psdp = instances[i].sbus;
+ devBus = NULL;
+ dev = NULL;
+ if (useProm && psdp->node.node)
+ promPath = sparcPromNode2Pathname(&psdp->node);
+
+ for (j = 0; j < numDevs; j++) {
+ if (devList[j]->busID && *devList[j]->busID) {
+ if (xf86CompareSbusBusString(devList[j]->busID, psdp->fbNum)) {
+ if (devBus)
+ xf86MsgVerb(X_WARNING,0,
+ "%s: More than one matching Device section for "
+ "instance (BusID: %s) found: %s\n",
+ driverName,devList[j]->identifier,
+ devList[j]->busID);
+ else
+ devBus = devList[j];
+ }
+ } else {
+ if (!dev && !devBus) {
+ if (promPath)
+ xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:%s\n",
+ promPath);
+ else
+ xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:fb%d\n",
+ psdp->fbNum);
+ dev = devList[j];
+ } else
+ xf86MsgVerb(X_WARNING, 0,
+ "%s: More than one matching Device section "
+ "found: %s\n", driverName, devList[j]->identifier);
+ }
+ }
+ if (devBus) dev = devBus; /* busID preferred */
+ if (!dev && psdp->fd != -2) {
+ if (promPath) {
+ xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
+ "for instance (BusID SBUS:%s) found\n",
+ driverName, promPath);
+ } else
+ xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
+ "for instance (BusID SBUS:fb%d) found\n",
+ driverName, psdp->fbNum);
+ } else if (dev) {
+ numClaimedInstances++;
+ instances[i].claimed = TRUE;
+ instances[i].dev = dev;
+ }
+ free(promPath);
+ }
+
+ DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
+
+ /*
+ * Of the claimed instances, check that another driver hasn't already
+ * claimed its slot.
+ */
+ numFound = 0;
+ for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
+ if (!instances[i].claimed)
+ continue;
+ psdp = instances[i].sbus;
+ if (!xf86CheckSbusSlot(psdp->fbNum))
+ continue;
+
+ DebugF("%s: card at fb%d %08x is claimed by a Device section\n",
+ driverName, psdp->fbNum, psdp->node.node);
+
+ /* Allocate an entry in the lists to be returned */
+ numFound++;
+ retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
+ retEntities[numFound - 1]
+ = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev,instances[i].dev->active ?
+ TRUE : FALSE);
+ }
+ free(instances);
+ if (numFound > 0) {
+ *foundEntities = retEntities;
+ }
+
+ if (useProm)
+ sparcPromClose();
+
+ return numFound;
+}
+
+/*
+ * xf86GetSbusInfoForEntity() -- Get the sbusDevicePtr of entity.
+ */
+sbusDevicePtr
+xf86GetSbusInfoForEntity(int entityIndex)
+{
+ sbusDevicePtr *psdpp;
+ EntityPtr p = xf86Entities[entityIndex];
+
+ if (entityIndex >= xf86NumEntities
+ || p->bus.type != BUS_SBUS) return NULL;
+
+ for (psdpp = xf86SbusInfo; *psdpp != NULL; psdpp++) {
+ if (p->bus.id.sbus.fbNum == (*psdpp)->fbNum)
+ return *psdpp;
+ }
+ return NULL;
+}
+
+int
+xf86GetEntityForSbusInfo(sbusDevicePtr psdp)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++) {
+ EntityPtr p = xf86Entities[i];
+ if (p->bus.type != BUS_SBUS) continue;
+
+ if (p->bus.id.sbus.fbNum == psdp->fbNum)
+ return i;
+ }
+ return -1;
+}
+
+void
+xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn, sbusDevicePtr psdp)
+{
+ DisplayModePtr mode;
+
+ mode = xnfcalloc(sizeof(DisplayModeRec), 1);
+ mode->name = "current";
+ mode->next = mode;
+ mode->prev = mode;
+ mode->type = M_T_BUILTIN;
+ mode->Clock = 100000000;
+ mode->HDisplay = psdp->width;
+ mode->HSyncStart = psdp->width;
+ mode->HSyncEnd = psdp->width;
+ mode->HTotal = psdp->width;
+ mode->VDisplay = psdp->height;
+ mode->VSyncStart = psdp->height;
+ mode->VSyncEnd = psdp->height;
+ mode->VTotal = psdp->height;
+ mode->SynthClock = mode->Clock;
+ mode->CrtcHDisplay = mode->HDisplay;
+ mode->CrtcHSyncStart = mode->HSyncStart;
+ mode->CrtcHSyncEnd = mode->HSyncEnd;
+ mode->CrtcHTotal = mode->HTotal;
+ mode->CrtcVDisplay = mode->VDisplay;
+ mode->CrtcVSyncStart = mode->VSyncStart;
+ mode->CrtcVSyncEnd = mode->VSyncEnd;
+ mode->CrtcVTotal = mode->VTotal;
+ mode->CrtcHAdjusted = FALSE;
+ mode->CrtcVAdjusted = FALSE;
+ pScrn->modes = mode;
+ pScrn->virtualX = psdp->width;
+ pScrn->virtualY = psdp->height;
+}
+
+static sbusPaletteKeyIndex;
+static DevPrivateKey sbusPaletteKey = &sbusPaletteKeyIndex;
+typedef struct _sbusCmap {
+ sbusDevicePtr psdp;
+ CloseScreenProcPtr CloseScreen;
+ Bool origCmapValid;
+ unsigned char origRed[16];
+ unsigned char origGreen[16];
+ unsigned char origBlue[16];
+} sbusCmapRec, *sbusCmapPtr;
+
+#define SBUSCMAPPTR(pScreen) ((sbusCmapPtr) \
+ dixLookupPrivate(&(pScreen)->devPrivates, sbusPaletteKey))
+
+static void
+xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual)
+{
+ int i, index;
+ sbusCmapPtr cmap;
+ struct fbcmap fbcmap;
+ unsigned char *data = malloc(numColors*3);
+
+ cmap = SBUSCMAPPTR(pScrn->pScreen);
+ if (!cmap) return;
+ fbcmap.count = 0;
+ fbcmap.index = indices[0];
+ fbcmap.red = data;
+ fbcmap.green = data + numColors;
+ fbcmap.blue = fbcmap.green + numColors;
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ if (fbcmap.count && index != fbcmap.index + fbcmap.count) {
+ ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
+ fbcmap.count = 0;
+ fbcmap.index = index;
+ }
+ fbcmap.red[fbcmap.count] = colors[index].red;
+ fbcmap.green[fbcmap.count] = colors[index].green;
+ fbcmap.blue[fbcmap.count++] = colors[index].blue;
+ }
+ ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
+ free(data);
+}
+
+static Bool
+xf86SbusCmapCloseScreen(int i, ScreenPtr pScreen)
+{
+ sbusCmapPtr cmap;
+ struct fbcmap fbcmap;
+
+ cmap = SBUSCMAPPTR(pScreen);
+ if (cmap->origCmapValid) {
+ fbcmap.index = 0;
+ fbcmap.count = 16;
+ fbcmap.red = cmap->origRed;
+ fbcmap.green = cmap->origGreen;
+ fbcmap.blue = cmap->origBlue;
+ ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
+ }
+ pScreen->CloseScreen = cmap->CloseScreen;
+ free(cmap);
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+Bool
+xf86SbusHandleColormaps(ScreenPtr pScreen, sbusDevicePtr psdp)
+{
+ sbusCmapPtr cmap;
+ struct fbcmap fbcmap;
+ unsigned char data[2];
+
+ cmap = xnfcalloc(1, sizeof(sbusCmapRec));
+ dixSetPrivate(&pScreen->devPrivates, sbusPaletteKey, cmap);
+ cmap->psdp = psdp;
+ fbcmap.index = 0;
+ fbcmap.count = 16;
+ fbcmap.red = cmap->origRed;
+ fbcmap.green = cmap->origGreen;
+ fbcmap.blue = cmap->origBlue;
+ if (ioctl (psdp->fd, FBIOGETCMAP, &fbcmap) >= 0)
+ cmap->origCmapValid = TRUE;
+ fbcmap.index = 0;
+ fbcmap.count = 2;
+ fbcmap.red = data;
+ fbcmap.green = data;
+ fbcmap.blue = data;
+ if (pScreen->whitePixel == 0) {
+ data[0] = 255;
+ data[1] = 0;
+ } else {
+ data[0] = 0;
+ data[1] = 255;
+ }
+ ioctl (psdp->fd, FBIOPUTCMAP, &fbcmap);
+ cmap->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xf86SbusCmapCloseScreen;
+ return xf86HandleColormaps(pScreen, 256, 8,
+ xf86SbusCmapLoadPalette, NULL, 0);
+}
+
+Bool
+xf86SbusConfigure(void *busData, sbusDevicePtr sBus)
+{
+ if (sBus && sBus->fbNum == ((sbusDevicePtr) busData)->fbNum)
+ return 0;
+ return 1;
+}
+
+void
+xf86SbusConfigureNewDev(void *busData, sbusDevicePtr sBus, GDevRec *GDev)
+{
+ char *promPath = NULL;
+
+ sBus = (sbusDevicePtr) busData;
+ GDev->identifier = sBus->descr;
+ if (sparcPromInit() >= 0) {
+ promPath = sparcPromNode2Pathname(&sBus->node);
+ sparcPromClose();
+ }
+ if (promPath) {
+ XNFasprintf(&GDev->busID, "SBUS:%s", promPath);
+ free(promPath);
+ } else {
+ XNFasprintf(&GDev->busID, "SBUS:fb%d", sBus->fbNum);
+ }
+}
diff --git a/xorg-server/hw/xfree86/common/xf86xv.c b/xorg-server/hw/xfree86/common/xf86xv.c
index b46dfefed..416842473 100644
--- a/xorg-server/hw/xfree86/common/xf86xv.c
+++ b/xorg-server/hw/xfree86/common/xf86xv.c
@@ -1,2190 +1,2190 @@
-/*
- * XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com)
- */
-/*
- * 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).
- */
-
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "scrnintstr.h"
-#include "regionstr.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "mivalidate.h"
-#include "validate.h"
-#include "resource.h"
-#include "gcstruct.h"
-#include "dixstruct.h"
-
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvproto.h>
-#include "xvdix.h"
-#include "xvmodproc.h"
-
-#include "xf86xvpriv.h"
-
-
-/* XvScreenRec fields */
-
-static Bool xf86XVCloseScreen(int, ScreenPtr);
-static int xf86XVQueryAdaptors(ScreenPtr, XvAdaptorPtr *, int *);
-
-/* XvAdaptorRec fields */
-
-static int xf86XVAllocatePort(unsigned long, XvPortPtr, XvPortPtr*);
-static int xf86XVFreePort(XvPortPtr);
-static int xf86XVPutVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int xf86XVPutStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int xf86XVGetVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int xf86XVGetStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int xf86XVStopVideo(ClientPtr, XvPortPtr, DrawablePtr);
-static int xf86XVSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32);
-static int xf86XVGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32*);
-static int xf86XVQueryBestSize(ClientPtr, XvPortPtr, CARD8,
- CARD16, CARD16,CARD16, CARD16,
- unsigned int*, unsigned int*);
-static int xf86XVPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16,
- XvImagePtr, unsigned char*, Bool,
- CARD16, CARD16);
-static int xf86XVQueryImageAttributes(ClientPtr, XvPortPtr, XvImagePtr,
- CARD16*, CARD16*, int*, int*);
-
-
-/* ScreenRec fields */
-
-static Bool xf86XVDestroyWindow(WindowPtr pWin);
-static void xf86XVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2);
-static void xf86XVPostValidateTree(WindowPtr pWin, WindowPtr pLayerWin, VTKind kind);
-static void xf86XVClipNotify(WindowPtr pWin, int dx, int dy);
-
-#define PostValidateTreeUndefined ((PostValidateTreeProcPtr)-1)
-
-/* ScrnInfoRec functions */
-
-static Bool xf86XVEnterVT(int, int);
-static void xf86XVLeaveVT(int, int);
-static void xf86XVAdjustFrame(int index, int x, int y, int flags);
-static void xf86XVModeSet(ScrnInfoPtr pScrn);
-
-/* misc */
-
-static Bool xf86XVInitAdaptors(ScreenPtr, XF86VideoAdaptorPtr*, int);
-
-
-static DevPrivateKeyRec XF86XVWindowKeyRec;
-#define XF86XVWindowKey (&XF86XVWindowKeyRec)
-
-DevPrivateKey XF86XvScreenKey;
-
-static unsigned long PortResource = 0;
-
-DevPrivateKey (*XvGetScreenKeyProc)(void) = NULL;
-unsigned long (*XvGetRTPortProc)(void) = NULL;
-int (*XvScreenInitProc)(ScreenPtr) = NULL;
-
-#define GET_XV_SCREEN(pScreen) \
- ((XvScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, XF86XvScreenKey))
-
-#define GET_XF86XV_SCREEN(pScreen) \
- ((XF86XVScreenPtr)(GET_XV_SCREEN(pScreen)->devPriv.ptr))
-
-#define GET_XF86XV_WINDOW(pWin) \
- ((XF86XVWindowPtr)dixLookupPrivate(&(pWin)->devPrivates, XF86XVWindowKey))
-
-static xf86XVInitGenericAdaptorPtr *GenDrivers = NULL;
-static int NumGenDrivers = 0;
-
-int
-xf86XVRegisterGenericAdaptorDriver(
- xf86XVInitGenericAdaptorPtr InitFunc
-){
- xf86XVInitGenericAdaptorPtr *newdrivers;
-
- newdrivers = realloc(GenDrivers, sizeof(xf86XVInitGenericAdaptorPtr) *
- (1 + NumGenDrivers));
- if (!newdrivers)
- return 0;
- GenDrivers = newdrivers;
-
- GenDrivers[NumGenDrivers++] = InitFunc;
-
- return 1;
-}
-
-int
-xf86XVListGenericAdaptors(
- ScrnInfoPtr pScrn,
- XF86VideoAdaptorPtr **adaptors
-){
- int i,j,n,num;
- XF86VideoAdaptorPtr *DrivAdap,*new;
-
- num = 0;
- *adaptors = NULL;
- /*
- * The v4l driver registers itself first, but can use surfaces registered
- * by other drivers. So, call the v4l driver last.
- */
- for (i = NumGenDrivers; --i >= 0; ) {
- DrivAdap = NULL;
- n = (*GenDrivers[i])(pScrn, &DrivAdap);
- if (0 == n)
- continue;
- new = realloc(*adaptors, sizeof(XF86VideoAdaptorPtr) * (num+n));
- if (NULL == new)
- continue;
- *adaptors = new;
- for (j = 0; j < n; j++, num++)
- (*adaptors)[num] = DrivAdap[j];
- }
- return num;
-}
-
-
-/**************** Offscreen surface stuff *******************/
-
-typedef struct {
- XF86OffscreenImagePtr images;
- int num;
-} OffscreenImageRec;
-
-static DevPrivateKeyRec OffscreenPrivateKeyRec;
-#define OffscreenPrivateKey (&OffscreenPrivateKeyRec)
-#define GetOffscreenImage(pScreen) ((OffscreenImageRec *) dixLookupPrivate(&(pScreen)->devPrivates, OffscreenPrivateKey))
-
-Bool
-xf86XVRegisterOffscreenImages(
- ScreenPtr pScreen,
- XF86OffscreenImagePtr images,
- int num
-){
- OffscreenImageRec *OffscreenImage;
- /* This function may be called before xf86XVScreenInit, so there's
- * no better place than this to call dixRegisterPrivateKey to ensure we
- * have space reserved. After the first call it is a no-op. */
- if(!dixRegisterPrivateKey(OffscreenPrivateKey, PRIVATE_SCREEN, sizeof(OffscreenImageRec)) ||
- !(OffscreenImage = GetOffscreenImage(pScreen)))
- /* Every X.org driver assumes this function always succeeds, so
- * just die on allocation failure. */
- FatalError("Could not allocate private storage for XV offscreen images.\n");
-
- OffscreenImage->num = num;
- OffscreenImage->images = images;
- return TRUE;
-}
-
-XF86OffscreenImagePtr
-xf86XVQueryOffscreenImages(
- ScreenPtr pScreen,
- int *num
-){
- OffscreenImageRec *OffscreenImage = GetOffscreenImage(pScreen);
- *num = OffscreenImage->num;
- return OffscreenImage->images;
-}
-
-
-XF86VideoAdaptorPtr
-xf86XVAllocateVideoAdaptorRec(ScrnInfoPtr pScrn)
-{
- return calloc(1, sizeof(XF86VideoAdaptorRec));
-}
-
-void
-xf86XVFreeVideoAdaptorRec(XF86VideoAdaptorPtr ptr)
-{
- free(ptr);
-}
-
-
-Bool
-xf86XVScreenInit(
- ScreenPtr pScreen,
- XF86VideoAdaptorPtr *adaptors,
- int num
-){
- ScrnInfoPtr pScrn;
- XF86XVScreenPtr ScreenPriv;
- XvScreenPtr pxvs;
-
- if(num <= 0 ||
- !XvGetScreenKeyProc || !XvGetRTPortProc || !XvScreenInitProc)
- return FALSE;
-
- if(Success != (*XvScreenInitProc)(pScreen)) return FALSE;
-
- if (!dixRegisterPrivateKey(&XF86XVWindowKeyRec, PRIVATE_WINDOW, 0))
- return FALSE;
-
- XF86XvScreenKey = (*XvGetScreenKeyProc)();
-
- PortResource = (*XvGetRTPortProc)();
-
- pxvs = GET_XV_SCREEN(pScreen);
-
- /* Anyone initializing the Xv layer must provide these two.
- The Xv di layer calls them without even checking if they exist! */
-
- pxvs->ddCloseScreen = xf86XVCloseScreen;
- pxvs->ddQueryAdaptors = xf86XVQueryAdaptors;
-
- /* The Xv di layer provides us with a private hook so that we don't
- have to allocate our own screen private. They also provide
- a CloseScreen hook so that we don't have to wrap it. I'm not
- sure that I appreciate that. */
-
- ScreenPriv = malloc(sizeof(XF86XVScreenRec));
- pxvs->devPriv.ptr = (pointer)ScreenPriv;
-
- if(!ScreenPriv) return FALSE;
-
- pScrn = xf86Screens[pScreen->myNum];
-
- ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
- ScreenPriv->WindowExposures = pScreen->WindowExposures;
- ScreenPriv->PostValidateTree = PostValidateTreeUndefined;
- ScreenPriv->ClipNotify = pScreen->ClipNotify;
- ScreenPriv->EnterVT = pScrn->EnterVT;
- ScreenPriv->LeaveVT = pScrn->LeaveVT;
- ScreenPriv->AdjustFrame = pScrn->AdjustFrame;
- ScreenPriv->ModeSet = pScrn->ModeSet;
-
- pScreen->DestroyWindow = xf86XVDestroyWindow;
- pScreen->WindowExposures = xf86XVWindowExposures;
- pScreen->ClipNotify = xf86XVClipNotify;
- pScrn->EnterVT = xf86XVEnterVT;
- pScrn->LeaveVT = xf86XVLeaveVT;
- if(pScrn->AdjustFrame)
- pScrn->AdjustFrame = xf86XVAdjustFrame;
- pScrn->ModeSet = xf86XVModeSet;
-
- if(!xf86XVInitAdaptors(pScreen, adaptors, num))
- return FALSE;
-
- return TRUE;
-}
-
-static void
-xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)
-{
- int i;
-
- free(pAdaptor->name);
- pAdaptor->name = NULL;
-
- if(pAdaptor->pEncodings) {
- XvEncodingPtr pEncode = pAdaptor->pEncodings;
-
- for(i = 0; i < pAdaptor->nEncodings; i++, pEncode++)
- free(pEncode->name);
- free(pAdaptor->pEncodings);
- pAdaptor->pEncodings = NULL;
- }
-
- free(pAdaptor->pFormats);
- pAdaptor->pFormats = NULL;
-
- if(pAdaptor->pPorts) {
- XvPortPtr pPort = pAdaptor->pPorts;
- XvPortRecPrivatePtr pPriv;
-
- for(i = 0; i < pAdaptor->nPorts; i++, pPort++) {
- pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
- if(pPriv) {
- if(pPriv->clientClip)
- RegionDestroy(pPriv->clientClip);
- if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
- RegionDestroy(pPriv->pCompositeClip);
- if (pPriv->ckeyFilled)
- RegionDestroy(pPriv->ckeyFilled);
- free(pPriv);
- }
- }
- free(pAdaptor->pPorts);
- pAdaptor->pPorts = NULL;
- }
-
- if(pAdaptor->pAttributes) {
- XvAttributePtr pAttribute = pAdaptor->pAttributes;
-
- for(i = 0; i < pAdaptor->nAttributes; i++, pAttribute++)
- free(pAttribute->name);
- free(pAdaptor->pAttributes);
- pAdaptor->pAttributes = NULL;
- }
-
- free(pAdaptor->pImages);
- free(pAdaptor->devPriv.ptr);
- pAdaptor->pImages = NULL;
- pAdaptor->devPriv.ptr = NULL;
-}
-
-static Bool
-xf86XVInitAdaptors(
- ScreenPtr pScreen,
- XF86VideoAdaptorPtr *infoPtr,
- int number
-) {
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XF86VideoAdaptorPtr adaptorPtr;
- XvAdaptorPtr pAdaptor, pa;
- XvAdaptorRecPrivatePtr adaptorPriv;
- int na, numAdaptor;
- XvPortRecPrivatePtr portPriv;
- XvPortPtr pPort, pp;
- int numPort;
- XF86AttributePtr attributePtr;
- XvAttributePtr pAttribute, pat;
- XF86VideoFormatPtr formatPtr;
- XvFormatPtr pFormat, pf;
- int numFormat, totFormat;
- XF86VideoEncodingPtr encodingPtr;
- XvEncodingPtr pEncode, pe;
- XF86ImagePtr imagePtr;
- XvImagePtr pImage, pi;
- int numVisuals;
- VisualPtr pVisual;
- int i;
-
- pxvs->nAdaptors = 0;
- pxvs->pAdaptors = NULL;
-
- if(!(pAdaptor = calloc(number, sizeof(XvAdaptorRec))))
- return FALSE;
-
- for(pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
- adaptorPtr = infoPtr[na];
-
- if(!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
- !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
- continue;
-
- /* client libs expect at least one encoding */
- if(!adaptorPtr->nEncodings || !adaptorPtr->pEncodings)
- continue;
-
- pa->type = adaptorPtr->type;
-
- if(!adaptorPtr->PutVideo && !adaptorPtr->GetVideo)
- pa->type &= ~XvVideoMask;
-
- if(!adaptorPtr->PutStill && !adaptorPtr->GetStill)
- pa->type &= ~XvStillMask;
-
- if(!adaptorPtr->PutImage || !adaptorPtr->QueryImageAttributes)
- pa->type &= ~XvImageMask;
-
- if(!adaptorPtr->PutVideo && !adaptorPtr->PutImage &&
- !adaptorPtr->PutStill)
- pa->type &= ~XvInputMask;
-
- if(!adaptorPtr->GetVideo && !adaptorPtr->GetStill)
- pa->type &= ~XvOutputMask;
-
- if(!(adaptorPtr->type & (XvPixmapMask | XvWindowMask)))
- continue;
- if(!(adaptorPtr->type & (XvImageMask | XvVideoMask | XvStillMask)))
- continue;
-
- pa->pScreen = pScreen;
- pa->ddAllocatePort = xf86XVAllocatePort;
- pa->ddFreePort = xf86XVFreePort;
- pa->ddPutVideo = xf86XVPutVideo;
- pa->ddPutStill = xf86XVPutStill;
- pa->ddGetVideo = xf86XVGetVideo;
- pa->ddGetStill = xf86XVGetStill;
- pa->ddStopVideo = xf86XVStopVideo;
- pa->ddPutImage = xf86XVPutImage;
- pa->ddSetPortAttribute = xf86XVSetPortAttribute;
- pa->ddGetPortAttribute = xf86XVGetPortAttribute;
- pa->ddQueryBestSize = xf86XVQueryBestSize;
- pa->ddQueryImageAttributes = xf86XVQueryImageAttributes;
- pa->name = strdup(adaptorPtr->name);
-
- if(adaptorPtr->nEncodings &&
- (pEncode = calloc(adaptorPtr->nEncodings, sizeof(XvEncodingRec)))) {
-
- for(pe = pEncode, encodingPtr = adaptorPtr->pEncodings, i = 0;
- i < adaptorPtr->nEncodings; pe++, i++, encodingPtr++)
- {
- pe->id = encodingPtr->id;
- pe->pScreen = pScreen;
- pe->name = strdup(encodingPtr->name);
- pe->width = encodingPtr->width;
- pe->height = encodingPtr->height;
- pe->rate.numerator = encodingPtr->rate.numerator;
- pe->rate.denominator = encodingPtr->rate.denominator;
- }
- pa->nEncodings = adaptorPtr->nEncodings;
- pa->pEncodings = pEncode;
- }
-
- if(adaptorPtr->nImages &&
- (pImage = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
-
- for(i = 0, pi = pImage, imagePtr = adaptorPtr->pImages;
- i < adaptorPtr->nImages; i++, pi++, imagePtr++)
- {
- pi->id = imagePtr->id;
- pi->type = imagePtr->type;
- pi->byte_order = imagePtr->byte_order;
- memcpy(pi->guid, imagePtr->guid, 16);
- pi->bits_per_pixel = imagePtr->bits_per_pixel;
- pi->format = imagePtr->format;
- pi->num_planes = imagePtr->num_planes;
- pi->depth = imagePtr->depth;
- pi->red_mask = imagePtr->red_mask;
- pi->green_mask = imagePtr->green_mask;
- pi->blue_mask = imagePtr->blue_mask;
- pi->y_sample_bits = imagePtr->y_sample_bits;
- pi->u_sample_bits = imagePtr->u_sample_bits;
- pi->v_sample_bits = imagePtr->v_sample_bits;
- pi->horz_y_period = imagePtr->horz_y_period;
- pi->horz_u_period = imagePtr->horz_u_period;
- pi->horz_v_period = imagePtr->horz_v_period;
- pi->vert_y_period = imagePtr->vert_y_period;
- pi->vert_u_period = imagePtr->vert_u_period;
- pi->vert_v_period = imagePtr->vert_v_period;
- memcpy(pi->component_order, imagePtr->component_order, 32);
- pi->scanline_order = imagePtr->scanline_order;
- }
- pa->nImages = adaptorPtr->nImages;
- pa->pImages = pImage;
- }
-
- if(adaptorPtr->nAttributes &&
- (pAttribute = calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec))))
- {
- for(pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i = 0;
- i < adaptorPtr->nAttributes; pat++, i++, attributePtr++)
- {
- pat->flags = attributePtr->flags;
- pat->min_value = attributePtr->min_value;
- pat->max_value = attributePtr->max_value;
- pat->name = strdup(attributePtr->name);
- }
- pa->nAttributes = adaptorPtr->nAttributes;
- pa->pAttributes = pAttribute;
- }
-
-
- totFormat = adaptorPtr->nFormats;
-
- if(!(pFormat = calloc(totFormat, sizeof(XvFormatRec)))) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
- for(pf = pFormat, i = 0, numFormat = 0, formatPtr = adaptorPtr->pFormats;
- i < adaptorPtr->nFormats; i++, formatPtr++)
- {
- numVisuals = pScreen->numVisuals;
- pVisual = pScreen->visuals;
-
- while(numVisuals--) {
- if((pVisual->class == formatPtr->class) &&
- (pVisual->nplanes == formatPtr->depth)) {
-
- if(numFormat >= totFormat) {
- void *moreSpace;
- totFormat *= 2;
- moreSpace = realloc(pFormat,
- totFormat * sizeof(XvFormatRec));
- if(!moreSpace) break;
- pFormat = moreSpace;
- pf = pFormat + numFormat;
- }
-
- pf->visual = pVisual->vid;
- pf->depth = formatPtr->depth;
-
- pf++;
- numFormat++;
- }
- pVisual++;
- }
- }
- pa->nFormats = numFormat;
- pa->pFormats = pFormat;
- if(!numFormat) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
-
- if(!(adaptorPriv = calloc(1, sizeof(XvAdaptorRecPrivate)))) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
-
- adaptorPriv->flags = adaptorPtr->flags;
- adaptorPriv->PutVideo = adaptorPtr->PutVideo;
- adaptorPriv->PutStill = adaptorPtr->PutStill;
- adaptorPriv->GetVideo = adaptorPtr->GetVideo;
- adaptorPriv->GetStill = adaptorPtr->GetStill;
- adaptorPriv->StopVideo = adaptorPtr->StopVideo;
- adaptorPriv->SetPortAttribute = adaptorPtr->SetPortAttribute;
- adaptorPriv->GetPortAttribute = adaptorPtr->GetPortAttribute;
- adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize;
- adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes;
- adaptorPriv->PutImage = adaptorPtr->PutImage;
- adaptorPriv->ReputImage = adaptorPtr->ReputImage; /* image/still */
-
- pa->devPriv.ptr = (pointer)adaptorPriv;
-
- if(!(pPort = calloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
- for(pp = pPort, i = 0, numPort = 0;
- i < adaptorPtr->nPorts; i++) {
-
- if(!(pp->id = FakeClientID(0)))
- continue;
-
- if(!(portPriv = calloc(1, sizeof(XvPortRecPrivate))))
- continue;
-
- if(!AddResource(pp->id, PortResource, pp)) {
- free(portPriv);
- continue;
- }
-
- pp->pAdaptor = pa;
- pp->pNotify = (XvPortNotifyPtr)NULL;
- pp->pDraw = (DrawablePtr)NULL;
- pp->client = (ClientPtr)NULL;
- pp->grab.client = (ClientPtr)NULL;
- pp->time = currentTime;
- pp->devPriv.ptr = portPriv;
-
- portPriv->pScrn = pScrn;
- portPriv->AdaptorRec = adaptorPriv;
- portPriv->DevPriv.ptr = adaptorPtr->pPortPrivates[i].ptr;
-
- pp++;
- numPort++;
- }
- pa->nPorts = numPort;
- pa->pPorts = pPort;
- if(!numPort) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
-
- pa->base_id = pPort->id;
-
- pa++;
- numAdaptor++;
- }
-
- if(numAdaptor) {
- pxvs->nAdaptors = numAdaptor;
- pxvs->pAdaptors = pAdaptor;
- } else {
- free(pAdaptor);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Video should be clipped to the intersection of the window cliplist
- and the client cliplist specified in the GC for which the video was
- initialized. When we need to reclip a window, the GC that started
- the video may not even be around anymore. That's why we save the
- client clip from the GC when the video is initialized. We then
- use xf86XVUpdateCompositeClip to calculate the new composite clip
- when we need it. This is different from what DEC did. They saved
- the GC and used it's clip list when they needed to reclip the window,
- even if the client clip was different from the one the video was
- initialized with. If the original GC was destroyed, they had to stop
- the video. I like the new method better (MArk).
-
- This function only works for windows. Will need to rewrite when
- (if) we support pixmap rendering.
-*/
-
-static void
-xf86XVUpdateCompositeClip(XvPortRecPrivatePtr portPriv)
-{
- RegionPtr pregWin, pCompositeClip;
- WindowPtr pWin;
- Bool freeCompClip = FALSE;
-
- if(portPriv->pCompositeClip)
- return;
-
- pWin = (WindowPtr)portPriv->pDraw;
-
- /* get window clip list */
- if(portPriv->subWindowMode == IncludeInferiors) {
- pregWin = NotClippedByChildren(pWin);
- freeCompClip = TRUE;
- } else
- pregWin = &pWin->clipList;
-
- if(!portPriv->clientClip) {
- portPriv->pCompositeClip = pregWin;
- portPriv->FreeCompositeClip = freeCompClip;
- return;
- }
-
- pCompositeClip = RegionCreate(NullBox, 1);
- RegionCopy(pCompositeClip, portPriv->clientClip);
- RegionTranslate(pCompositeClip,
- portPriv->pDraw->x, portPriv->pDraw->y);
- RegionIntersect(pCompositeClip, pregWin, pCompositeClip);
-
- portPriv->pCompositeClip = pCompositeClip;
- portPriv->FreeCompositeClip = TRUE;
-
- if(freeCompClip) {
- RegionDestroy(pregWin);
- }
-}
-
-/* Save the current clientClip and update the CompositeClip whenever
- we have a fresh GC */
-
-static void
-xf86XVCopyClip(
- XvPortRecPrivatePtr portPriv,
- GCPtr pGC
-){
- /* copy the new clip if it exists */
- if((pGC->clientClipType == CT_REGION) && pGC->clientClip) {
- if(!portPriv->clientClip)
- portPriv->clientClip = RegionCreate(NullBox, 1);
- /* Note: this is in window coordinates */
- RegionCopy(portPriv->clientClip, pGC->clientClip);
- RegionTranslate(portPriv->clientClip,
- pGC->clipOrg.x, pGC->clipOrg.y);
- } else if(portPriv->clientClip) { /* free the old clientClip */
- RegionDestroy(portPriv->clientClip);
- portPriv->clientClip = NULL;
- }
-
- /* get rid of the old clip list */
- if(portPriv->pCompositeClip && portPriv->FreeCompositeClip) {
- RegionDestroy(portPriv->pCompositeClip);
- }
-
- portPriv->pCompositeClip = pGC->pCompositeClip;
- portPriv->FreeCompositeClip = FALSE;
- portPriv->subWindowMode = pGC->subWindowMode;
-}
-
-static void
-xf86XVCopyCompositeClip(XvPortRecPrivatePtr portPriv,
- GCPtr pGC,
- DrawablePtr pDraw)
-{
- if (!portPriv->clientClip)
- portPriv->clientClip = RegionCreate(NullBox, 1);
- /* Keep the original GC composite clip around for ReputImage */
- RegionCopy(portPriv->clientClip, pGC->pCompositeClip);
- RegionTranslate(portPriv->clientClip,
- -pDraw->x, -pDraw->y);
-
- /* get rid of the old clip list */
- if (portPriv->pCompositeClip && portPriv->FreeCompositeClip)
- RegionDestroy(portPriv->pCompositeClip);
-
- portPriv->pCompositeClip = pGC->pCompositeClip;
- portPriv->FreeCompositeClip = FALSE;
- portPriv->subWindowMode = pGC->subWindowMode;
-}
-
-static int
-xf86XVRegetVideo(XvPortRecPrivatePtr portPriv)
-{
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- xf86XVUpdateCompositeClip(portPriv);
-
- /* translate the video region to the screen */
- WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
- WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
- WinBox.x2 = WinBox.x1 + portPriv->drw_w;
- WinBox.y2 = WinBox.y1 + portPriv->drw_h;
-
- /* clip to the window composite clip */
- RegionInit(&WinRegion, &WinBox, 1);
- RegionNull(&ClipRegion);
- RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
-
- /* that's all if it's totally obscured */
- if(!RegionNotEmpty(&ClipRegion)) {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->GetVideo)(portPriv->pScrn,
- portPriv->vid_x, portPriv->vid_y,
- WinBox.x1, WinBox.y1,
- portPriv->vid_w, portPriv->vid_h,
- portPriv->drw_w, portPriv->drw_h,
- &ClipRegion, portPriv->DevPriv.ptr,
- portPriv->pDraw);
-
- if(ret == Success)
- portPriv->isOn = XV_ON;
-
-CLIP_VIDEO_BAILOUT:
-
- if((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- /* This clip was copied and only good for one shot */
- if(!portPriv->FreeCompositeClip)
- portPriv->pCompositeClip = NULL;
-
- RegionUninit(&WinRegion);
- RegionUninit(&ClipRegion);
-
- return ret;
-}
-
-
-static int
-xf86XVReputVideo(XvPortRecPrivatePtr portPriv)
-{
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- xf86XVUpdateCompositeClip(portPriv);
-
- /* translate the video region to the screen */
- WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
- WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
- WinBox.x2 = WinBox.x1 + portPriv->drw_w;
- WinBox.y2 = WinBox.y1 + portPriv->drw_h;
-
- /* clip to the window composite clip */
- RegionInit(&WinRegion, &WinBox, 1);
- RegionNull(&ClipRegion);
- RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
-
- /* clip and translate to the viewport */
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = portPriv->pScrn->frameX0;
- VPBox.y1 = portPriv->pScrn->frameY0;
- VPBox.x2 = portPriv->pScrn->frameX1 + 1;
- VPBox.y2 = portPriv->pScrn->frameY1 + 1;
-
- RegionInit(&VPReg, &VPBox, 1);
- RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
- RegionUninit(&VPReg);
- }
-
- /* that's all if it's totally obscured */
- if(!RegionNotEmpty(&ClipRegion)) {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
-
- /* bailout if we have to clip but the hardware doesn't support it */
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = RegionRects(&ClipRegion);
- if( (RegionNumRects(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->PutVideo)(portPriv->pScrn,
- portPriv->vid_x, portPriv->vid_y,
- WinBox.x1, WinBox.y1,
- portPriv->vid_w, portPriv->vid_h,
- portPriv->drw_w, portPriv->drw_h,
- &ClipRegion, portPriv->DevPriv.ptr,
- portPriv->pDraw);
-
- if(ret == Success) portPriv->isOn = XV_ON;
-
-CLIP_VIDEO_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- /* This clip was copied and only good for one shot */
- if(!portPriv->FreeCompositeClip)
- portPriv->pCompositeClip = NULL;
-
- RegionUninit(&WinRegion);
- RegionUninit(&ClipRegion);
-
- return ret;
-}
-
-/* Reput image/still */
-static int
-xf86XVReputImage(XvPortRecPrivatePtr portPriv)
-{
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- xf86XVUpdateCompositeClip(portPriv);
-
- /* the clip can get smaller over time */
- RegionCopy(portPriv->clientClip, portPriv->pCompositeClip);
- RegionTranslate(portPriv->clientClip,
- -portPriv->pDraw->x, -portPriv->pDraw->y);
-
- /* translate the video region to the screen */
- WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
- WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
- WinBox.x2 = WinBox.x1 + portPriv->drw_w;
- WinBox.y2 = WinBox.y1 + portPriv->drw_h;
-
- /* clip to the window composite clip */
- RegionInit(&WinRegion, &WinBox, 1);
- RegionNull(&ClipRegion);
- RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
-
- /* clip and translate to the viewport */
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = portPriv->pScrn->frameX0;
- VPBox.y1 = portPriv->pScrn->frameY0;
- VPBox.x2 = portPriv->pScrn->frameX1 + 1;
- VPBox.y2 = portPriv->pScrn->frameY1 + 1;
-
- RegionInit(&VPReg, &VPBox, 1);
- RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
- RegionUninit(&VPReg);
- }
-
- /* that's all if it's totally obscured */
- if(!RegionNotEmpty(&ClipRegion)) {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
-
- /* bailout if we have to clip but the hardware doesn't support it */
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = RegionRects(&ClipRegion);
- if( (RegionNumRects(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->pScrn,
- portPriv->vid_x, portPriv->vid_y,
- WinBox.x1, WinBox.y1,
- portPriv->vid_w, portPriv->vid_h,
- portPriv->drw_w, portPriv->drw_h,
- &ClipRegion, portPriv->DevPriv.ptr,
- portPriv->pDraw);
-
- portPriv->isOn = (ret == Success) ? XV_ON : XV_OFF;
-
-CLIP_VIDEO_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- /* This clip was copied and only good for one shot */
- if(!portPriv->FreeCompositeClip)
- portPriv->pCompositeClip = NULL;
-
- RegionUninit(&WinRegion);
- RegionUninit(&ClipRegion);
-
- return ret;
-}
-
-
-static int
-xf86XVReputAllVideo(WindowPtr pWin, pointer data)
-{
- XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
-
- while(WinPriv) {
- if(WinPriv->PortRec->type == XvInputMask)
- xf86XVReputVideo(WinPriv->PortRec);
- else
- xf86XVRegetVideo(WinPriv->PortRec);
- WinPriv = WinPriv->next;
- }
-
- return WT_WALKCHILDREN;
-}
-
-static int
-xf86XVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
-{
- XF86XVWindowPtr winPriv, PrivRoot;
-
- winPriv = PrivRoot = GET_XF86XV_WINDOW(pWin);
-
- /* Enlist our port in the window private */
- while(winPriv) {
- if(winPriv->PortRec == portPriv) /* we're already listed */
- break;
- winPriv = winPriv->next;
- }
-
- if(!winPriv) {
- winPriv = calloc(1, sizeof(XF86XVWindowRec));
- if(!winPriv) return BadAlloc;
- winPriv->PortRec = portPriv;
- winPriv->next = PrivRoot;
- dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, winPriv);
- }
-
- portPriv->pDraw = (DrawablePtr)pWin;
-
- return Success;
-}
-
-
-static void
-xf86XVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
-{
- XF86XVWindowPtr winPriv, prevPriv = NULL;
- winPriv = GET_XF86XV_WINDOW(pWin);
-
- while(winPriv) {
- if(winPriv->PortRec == portPriv) {
- if(prevPriv)
- prevPriv->next = winPriv->next;
- else
- dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
- winPriv->next);
- free(winPriv);
- break;
- }
- prevPriv = winPriv;
- winPriv = winPriv->next;
- }
- portPriv->pDraw = NULL;
- if (portPriv->ckeyFilled) {
- RegionDestroy(portPriv->ckeyFilled);
- portPriv->ckeyFilled = NULL;
- }
- portPriv->clipChanged = FALSE;
-}
-
-static void
-xf86XVReputOrStopPort(XvPortRecPrivatePtr pPriv,
- WindowPtr pWin,
- Bool visible)
-{
- if (!visible) {
- if (pPriv->isOn == XV_ON) {
- (*pPriv->AdaptorRec->StopVideo)(pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
- pPriv->isOn = XV_PENDING;
- }
-
- if (!pPriv->type) /* overlaid still/image*/
- xf86XVRemovePortFromWindow(pWin, pPriv);
-
- return;
- }
-
- switch (pPriv->type) {
- case XvInputMask:
- xf86XVReputVideo(pPriv);
- break;
- case XvOutputMask:
- xf86XVRegetVideo(pPriv);
- break;
- default: /* overlaid still/image*/
- if (pPriv->AdaptorRec->ReputImage)
- xf86XVReputImage(pPriv);
- break;
- }
-}
-
-static void
-xf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn, Bool onlyChanged)
-{
- ScreenPtr pScreen = pScrn->pScreen;
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
- XvAdaptorPtr pa;
- int c, i;
-
- for (c = pxvs->nAdaptors, pa = pxvs->pAdaptors; c > 0; c--, pa++) {
- XvPortPtr pPort = pa->pPorts;
-
- for (i = pa->nPorts; i > 0; i--, pPort++) {
- XvPortRecPrivatePtr pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
- WindowPtr pWin = (WindowPtr)pPriv->pDraw;
- Bool visible;
-
- if (pPriv->isOn == XV_OFF || !pWin)
- continue;
-
- if (onlyChanged && !pPriv->clipChanged)
- continue;
-
- visible = pWin->visibility == VisibilityUnobscured ||
- pWin->visibility == VisibilityPartiallyObscured;
-
- /*
- * Stop and remove still/images if
- * ReputImage isn't supported.
- */
- if (!pPriv->type && !pPriv->AdaptorRec->ReputImage)
- visible = FALSE;
-
- xf86XVReputOrStopPort(pPriv, pWin, visible);
-
- pPriv->clipChanged = FALSE;
- }
- }
-}
-
-/**** ScreenRec fields ****/
-
-static Bool
-xf86XVDestroyWindow(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XF86XVWindowPtr tmp, WinPriv = GET_XF86XV_WINDOW(pWin);
- int ret;
-
- while(WinPriv) {
- XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
-
- if(pPriv->isOn > XV_OFF) {
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->pScrn, pPriv->DevPriv.ptr, TRUE);
- pPriv->isOn = XV_OFF;
- }
-
- pPriv->pDraw = NULL;
- tmp = WinPriv;
- WinPriv = WinPriv->next;
- free(tmp);
- }
-
- dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, NULL);
-
- pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
- ret = (*pScreen->DestroyWindow)(pWin);
- pScreen->DestroyWindow = xf86XVDestroyWindow;
-
- return ret;
-}
-
-static void
-xf86XVPostValidateTree(WindowPtr pWin, WindowPtr pLayerWin, VTKind kind)
-{
- ScreenPtr pScreen;
- XF86XVScreenPtr ScreenPriv;
- ScrnInfoPtr pScrn;
-
- if (pWin)
- pScreen = pWin->drawable.pScreen;
- else
- pScreen = pLayerWin->drawable.pScreen;
-
- ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- pScrn = xf86Screens[pScreen->myNum];
-
- xf86XVReputOrStopAllPorts(pScrn, TRUE);
-
- pScreen->PostValidateTree = ScreenPriv->PostValidateTree;
- if (pScreen->PostValidateTree) {
- (*pScreen->PostValidateTree)(pWin, pLayerWin, kind);
- }
- ScreenPriv->PostValidateTree = PostValidateTreeUndefined;
-}
-
-static void
-xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
- XvPortRecPrivatePtr pPriv;
- Bool AreasExposed;
-
- AreasExposed = (WinPriv && reg1 && RegionNotEmpty(reg1));
-
- pScreen->WindowExposures = ScreenPriv->WindowExposures;
- (*pScreen->WindowExposures)(pWin, reg1, reg2);
- pScreen->WindowExposures = xf86XVWindowExposures;
-
- /* filter out XClearWindow/Area */
- if (!pWin->valdata) return;
-
- while(WinPriv) {
- Bool visible = TRUE;
-
- pPriv = WinPriv->PortRec;
-
- /*
- * Stop and remove still/images if areas were exposed and
- * ReputImage isn't supported.
- */
- if (!pPriv->type && !pPriv->AdaptorRec->ReputImage)
- visible = !AreasExposed;
-
- /*
- * Subtract exposed areas from overlaid image to match textured video
- * behavior.
- */
- if (!pPriv->type && pPriv->clientClip)
- RegionSubtract(pPriv->clientClip, pPriv->clientClip, reg1);
-
- if (visible && pPriv->ckeyFilled) {
- RegionRec tmp;
- RegionNull(&tmp);
- RegionCopy(&tmp, reg1);
- RegionTranslate(&tmp, pWin->drawable.x, pWin->drawable.y);
- RegionSubtract(pPriv->ckeyFilled, pPriv->ckeyFilled, &tmp);
- }
-
- WinPriv = WinPriv->next;
- xf86XVReputOrStopPort(pPriv, pWin, visible);
-
- pPriv->clipChanged = FALSE;
- }
-}
-
-static void
-xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
- XvPortRecPrivatePtr pPriv;
-
- while(WinPriv) {
- pPriv = WinPriv->PortRec;
-
- if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
- RegionDestroy(pPriv->pCompositeClip);
-
- pPriv->pCompositeClip = NULL;
-
- if (pPriv->AdaptorRec->ClipNotify)
- (*pPriv->AdaptorRec->ClipNotify)(pPriv->pScrn, pPriv->DevPriv.ptr,
- pWin, dx, dy);
-
- pPriv->clipChanged = TRUE;
-
- if (ScreenPriv->PostValidateTree == PostValidateTreeUndefined) {
- ScreenPriv->PostValidateTree = pScreen->PostValidateTree;
- pScreen->PostValidateTree = xf86XVPostValidateTree;
- }
-
- WinPriv = WinPriv->next;
- }
-
- if(ScreenPriv->ClipNotify) {
- pScreen->ClipNotify = ScreenPriv->ClipNotify;
- (*pScreen->ClipNotify)(pWin, dx, dy);
- pScreen->ClipNotify = xf86XVClipNotify;
- }
-}
-
-
-
-/**** Required XvScreenRec fields ****/
-
-static Bool
-xf86XVCloseScreen(int i, ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XvAdaptorPtr pa;
- int c;
-
- if(!ScreenPriv) return TRUE;
-
- pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
- pScreen->WindowExposures = ScreenPriv->WindowExposures;
- pScreen->ClipNotify = ScreenPriv->ClipNotify;
-
- pScrn->EnterVT = ScreenPriv->EnterVT;
- pScrn->LeaveVT = ScreenPriv->LeaveVT;
- pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
- pScrn->ModeSet = ScreenPriv->ModeSet;
-
- for(c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) {
- xf86XVFreeAdaptor(pa);
- }
-
- free(pxvs->pAdaptors);
- free(ScreenPriv);
- return TRUE;
-}
-
-
-static int
-xf86XVQueryAdaptors(
- ScreenPtr pScreen,
- XvAdaptorPtr *p_pAdaptors,
- int *p_nAdaptors
-){
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
-
- *p_nAdaptors = pxvs->nAdaptors;
- *p_pAdaptors = pxvs->pAdaptors;
-
- return Success;
-}
-
-
-/**** ScrnInfoRec fields ****/
-
-static Bool
-xf86XVEnterVT(int index, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[index];
- ScreenPtr pScreen = screenInfo.screens[index];
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- Bool ret;
-
- pScrn->EnterVT = ScreenPriv->EnterVT;
- ret = (*ScreenPriv->EnterVT)(index, flags);
- ScreenPriv->EnterVT = pScrn->EnterVT;
- pScrn->EnterVT = xf86XVEnterVT;
-
- if(ret) WalkTree(pScreen, xf86XVReputAllVideo, 0);
-
- return ret;
-}
-
-static void
-xf86XVLeaveVT(int index, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[index];
- ScreenPtr pScreen = screenInfo.screens[index];
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XvAdaptorPtr pAdaptor;
- XvPortPtr pPort;
- XvPortRecPrivatePtr pPriv;
- int i, j;
-
- for(i = 0; i < pxvs->nAdaptors; i++) {
- pAdaptor = &pxvs->pAdaptors[i];
- for(j = 0; j < pAdaptor->nPorts; j++) {
- pPort = &pAdaptor->pPorts[j];
- pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
- if(pPriv->isOn > XV_OFF) {
-
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->pScrn, pPriv->DevPriv.ptr, TRUE);
- pPriv->isOn = XV_OFF;
-
- if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
- RegionDestroy(pPriv->pCompositeClip);
-
- pPriv->pCompositeClip = NULL;
-
- if(!pPriv->type && pPriv->pDraw) { /* still */
- xf86XVRemovePortFromWindow((WindowPtr)pPriv->pDraw, pPriv);
- }
- }
- }
- }
-
- pScrn->LeaveVT = ScreenPriv->LeaveVT;
- (*ScreenPriv->LeaveVT)(index, flags);
- ScreenPriv->LeaveVT = pScrn->LeaveVT;
- pScrn->LeaveVT = xf86XVLeaveVT;
-}
-
-static void
-xf86XVAdjustFrame(int index, int x, int y, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[index];
- ScreenPtr pScreen = pScrn->pScreen;
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
-
- if(ScreenPriv->AdjustFrame) {
- pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
- (*pScrn->AdjustFrame)(index, x, y, flags);
- pScrn->AdjustFrame = xf86XVAdjustFrame;
- }
-
- xf86XVReputOrStopAllPorts(pScrn, FALSE);
-}
-
-static void
-xf86XVModeSet(ScrnInfoPtr pScrn)
-{
- ScreenPtr pScreen = pScrn->pScreen;
- XF86XVScreenPtr ScreenPriv;
-
- /* Can be called before pScrn->pScreen is set */
- if (!pScreen)
- return;
-
- ScreenPriv = GET_XF86XV_SCREEN(pScreen);
-
- if (ScreenPriv->ModeSet) {
- pScrn->ModeSet = ScreenPriv->ModeSet;
- (*pScrn->ModeSet)(pScrn);
- pScrn->ModeSet = xf86XVModeSet;
- }
-
- xf86XVReputOrStopAllPorts(pScrn, FALSE);
-}
-
-/**** XvAdaptorRec fields ****/
-
-static int
-xf86XVAllocatePort(
- unsigned long port,
- XvPortPtr pPort,
- XvPortPtr *ppPort
-){
- *ppPort = pPort;
- return Success;
-}
-
-
-
-static int
-xf86XVFreePort(XvPortPtr pPort)
-{
- return Success;
-}
-
-
-static int
-xf86XVPutVideo(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- int result;
-
- /* No dumping video to pixmaps... For now anyhow */
- if(pDraw->type != DRAWABLE_WINDOW) {
- pPort->pDraw = (DrawablePtr)NULL;
- return BadAlloc;
- }
-
- /* If we are changing windows, unregister our port in the old window */
- if(portPriv->pDraw && (portPriv->pDraw != pDraw))
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
-
- /* Register our port with the new window */
- result = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- if(result != Success) return result;
-
- portPriv->type = XvInputMask;
-
- /* save a copy of these parameters */
- portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
- portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
-
- /* make sure we have the most recent copy of the clientClip */
- xf86XVCopyClip(portPriv, pGC);
-
- /* To indicate to the DI layer that we were successful */
- pPort->pDraw = pDraw;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- return(xf86XVReputVideo(portPriv));
-}
-
-static int
-xf86XVPutStill(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- if (pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- WinBox.x1 = pDraw->x + drw_x;
- WinBox.y1 = pDraw->y + drw_y;
- WinBox.x2 = WinBox.x1 + drw_w;
- WinBox.y2 = WinBox.y1 + drw_h;
-
- xf86XVCopyCompositeClip(portPriv, pGC, pDraw);
-
- RegionInit(&WinRegion, &WinBox, 1);
- RegionNull(&ClipRegion);
- RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
-
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = portPriv->pScrn->frameX0;
- VPBox.y1 = portPriv->pScrn->frameY0;
- VPBox.x2 = portPriv->pScrn->frameX1 + 1;
- VPBox.y2 = portPriv->pScrn->frameY1 + 1;
-
- RegionInit(&VPReg, &VPBox, 1);
- RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
- RegionUninit(&VPReg);
- }
-
- if(portPriv->pDraw) {
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
- }
-
- if(!RegionNotEmpty(&ClipRegion)) {
- clippedAway = TRUE;
- goto PUT_STILL_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = RegionRects(&ClipRegion);
- if( (RegionNumRects(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto PUT_STILL_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->PutStill)(portPriv->pScrn,
- vid_x, vid_y, WinBox.x1, WinBox.y1,
- vid_w, vid_h, drw_w, drw_h,
- &ClipRegion, portPriv->DevPriv.ptr,
- pDraw);
-
- if((ret == Success) &&
- (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_STILLS)) {
-
- xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- portPriv->isOn = XV_ON;
- portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
- portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
- portPriv->type = 0; /* no mask means it's transient and should
- not be reput once it's removed */
- pPort->pDraw = pDraw; /* make sure we can get stop requests */
- }
-
-PUT_STILL_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- /* This clip was copied and only good for one shot */
- if(!portPriv->FreeCompositeClip)
- portPriv->pCompositeClip = NULL;
-
- RegionUninit(&WinRegion);
- RegionUninit(&ClipRegion);
-
- return ret;
-}
-
-static int
-xf86XVGetVideo(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- int result;
-
- /* No pixmaps... For now anyhow */
- if(pDraw->type != DRAWABLE_WINDOW) {
- pPort->pDraw = (DrawablePtr)NULL;
- return BadAlloc;
- }
-
- /* If we are changing windows, unregister our port in the old window */
- if(portPriv->pDraw && (portPriv->pDraw != pDraw))
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
-
- /* Register our port with the new window */
- result = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- if(result != Success) return result;
-
- portPriv->type = XvOutputMask;
-
- /* save a copy of these parameters */
- portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
- portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
-
- /* make sure we have the most recent copy of the clientClip */
- xf86XVCopyClip(portPriv, pGC);
-
- /* To indicate to the DI layer that we were successful */
- pPort->pDraw = pDraw;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- return(xf86XVRegetVideo(portPriv));
-}
-
-static int
-xf86XVGetStill(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- if (pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- WinBox.x1 = pDraw->x + drw_x;
- WinBox.y1 = pDraw->y + drw_y;
- WinBox.x2 = WinBox.x1 + drw_w;
- WinBox.y2 = WinBox.y1 + drw_h;
-
- RegionInit(&WinRegion, &WinBox, 1);
- RegionNull(&ClipRegion);
- RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
-
- if(portPriv->pDraw) {
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
- }
-
- if(!RegionNotEmpty(&ClipRegion)) {
- clippedAway = TRUE;
- goto GET_STILL_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->GetStill)(portPriv->pScrn,
- vid_x, vid_y, WinBox.x1, WinBox.y1,
- vid_w, vid_h, drw_w, drw_h,
- &ClipRegion, portPriv->DevPriv.ptr,
- pDraw);
-
-GET_STILL_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- RegionUninit(&WinRegion);
- RegionUninit(&ClipRegion);
-
- return ret;
-}
-
-
-
-static int
-xf86XVStopVideo(
- ClientPtr client,
- XvPortPtr pPort,
- DrawablePtr pDraw
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- if(pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- xf86XVRemovePortFromWindow((WindowPtr)pDraw, portPriv);
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- /* Must free resources. */
-
- if(portPriv->isOn > XV_OFF) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, TRUE);
- portPriv->isOn = XV_OFF;
- }
-
- return Success;
-}
-
-static int
-xf86XVSetPortAttribute(
- ClientPtr client,
- XvPortPtr pPort,
- Atom attribute,
- INT32 value
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- return((*portPriv->AdaptorRec->SetPortAttribute)(portPriv->pScrn,
- attribute, value, portPriv->DevPriv.ptr));
-}
-
-
-static int
-xf86XVGetPortAttribute(
- ClientPtr client,
- XvPortPtr pPort,
- Atom attribute,
- INT32 *p_value
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- return((*portPriv->AdaptorRec->GetPortAttribute)(portPriv->pScrn,
- attribute, p_value, portPriv->DevPriv.ptr));
-}
-
-
-
-static int
-xf86XVQueryBestSize(
- ClientPtr client,
- XvPortPtr pPort,
- CARD8 motion,
- CARD16 vid_w, CARD16 vid_h,
- CARD16 drw_w, CARD16 drw_h,
- unsigned int *p_w, unsigned int *p_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- (*portPriv->AdaptorRec->QueryBestSize)(portPriv->pScrn,
- (Bool)motion, vid_w, vid_h, drw_w, drw_h,
- p_w, p_h, portPriv->DevPriv.ptr);
-
- return Success;
-}
-
-
-static int
-xf86XVPutImage(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 src_x, INT16 src_y,
- CARD16 src_w, CARD16 src_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h,
- XvImagePtr format,
- unsigned char* data,
- Bool sync,
- CARD16 width, CARD16 height
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- if (pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- xf86XVCopyCompositeClip(portPriv, pGC, pDraw);
-
- WinBox.x1 = pDraw->x + drw_x;
- WinBox.y1 = pDraw->y + drw_y;
- WinBox.x2 = WinBox.x1 + drw_w;
- WinBox.y2 = WinBox.y1 + drw_h;
-
- RegionInit(&WinRegion, &WinBox, 1);
- RegionNull(&ClipRegion);
- RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
-
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = portPriv->pScrn->frameX0;
- VPBox.y1 = portPriv->pScrn->frameY0;
- VPBox.x2 = portPriv->pScrn->frameX1 + 1;
- VPBox.y2 = portPriv->pScrn->frameY1 + 1;
-
- RegionInit(&VPReg, &VPBox, 1);
- RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
- RegionUninit(&VPReg);
- }
-
- /* If we are changing windows, unregister our port in the old window */
- if(portPriv->pDraw && (portPriv->pDraw != pDraw))
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
-
- /* Register our port with the new window */
- ret = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- if(ret != Success) goto PUT_IMAGE_BAILOUT;
-
- if(!RegionNotEmpty(&ClipRegion)) {
- clippedAway = TRUE;
- goto PUT_IMAGE_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = RegionRects(&ClipRegion);
- if( (RegionNumRects(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto PUT_IMAGE_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->PutImage)(portPriv->pScrn,
- src_x, src_y, WinBox.x1, WinBox.y1,
- src_w, src_h, drw_w, drw_h, format->id, data, width, height,
- sync, &ClipRegion, portPriv->DevPriv.ptr,
- pDraw);
-
- if((ret == Success) &&
- (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) {
-
- portPriv->isOn = XV_ON;
- portPriv->vid_x = src_x; portPriv->vid_y = src_y;
- portPriv->vid_w = src_w; portPriv->vid_h = src_h;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
- portPriv->type = 0; /* no mask means it's transient and should
- not be reput once it's removed */
- pPort->pDraw = pDraw; /* make sure we can get stop requests */
- }
-
-PUT_IMAGE_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- /* This clip was copied and only good for one shot */
- if(!portPriv->FreeCompositeClip)
- portPriv->pCompositeClip = NULL;
-
- RegionUninit(&WinRegion);
- RegionUninit(&ClipRegion);
-
- return ret;
-}
-
-
-static int
-xf86XVQueryImageAttributes(
- ClientPtr client,
- XvPortPtr pPort,
- XvImagePtr format,
- CARD16 *width,
- CARD16 *height,
- int *pitches,
- int *offsets
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- return (*portPriv->AdaptorRec->QueryImageAttributes)(portPriv->pScrn,
- format->id, width, height, pitches, offsets);
-}
-
-void
-xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr fillboxes)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- ChangeGCVal pval[2];
- BoxPtr pbox = RegionRects(fillboxes);
- int i, nbox = RegionNumRects(fillboxes);
- xRectangle *rects;
- GCPtr gc;
-
- if(!xf86Screens[pScreen->myNum]->vtSema) return;
-
- gc = GetScratchGC(pDraw->depth, pScreen);
- pval[0].val = key;
- pval[1].val = IncludeInferiors;
- (void) ChangeGC(NullClient, gc, GCForeground|GCSubwindowMode, pval);
- ValidateGC(pDraw, gc);
-
- rects = malloc(nbox * sizeof(xRectangle));
-
- for(i = 0; i < nbox; i++, pbox++)
- {
- rects[i].x = pbox->x1 - pDraw->x;
- rects[i].y = pbox->y1 - pDraw->y;
- rects[i].width = pbox->x2 - pbox->x1;
- rects[i].height = pbox->y2 - pbox->y1;
- }
-
- (*gc->ops->PolyFillRect)(pDraw, gc, nbox, rects);
-
- free(rects);
- FreeScratchGC (gc);
-}
-
-void
-xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr fillboxes)
-{
- xf86XVFillKeyHelperDrawable (&pScreen->root->drawable, key, fillboxes);
-}
-
-void
-xf86XVFillKeyHelperPort (DrawablePtr pDraw, pointer data, CARD32 key, RegionPtr clipboxes, Bool fillEverything)
-{
- WindowPtr pWin = (WindowPtr)pDraw;
- XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
- XvPortRecPrivatePtr portPriv = NULL;
- RegionRec reg;
- RegionPtr fillboxes;
-
- while (WinPriv) {
- XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
-
- if (data == pPriv->DevPriv.ptr) {
- portPriv = pPriv;
- break;
- }
-
- WinPriv = WinPriv->next;
- }
-
- if (!portPriv)
- return;
-
- if (!portPriv->ckeyFilled)
- portPriv->ckeyFilled = RegionCreate(NULL, 0);
-
- if (!fillEverything) {
- RegionNull(&reg);
- fillboxes = &reg;
- RegionSubtract(fillboxes, clipboxes, portPriv->ckeyFilled);
-
- if (!RegionNotEmpty(fillboxes))
- goto out;
- } else
- fillboxes = clipboxes;
-
-
- RegionCopy(portPriv->ckeyFilled, clipboxes);
-
- xf86XVFillKeyHelperDrawable(pDraw, key, fillboxes);
-out:
- if (!fillEverything)
- RegionUninit(&reg);
-}
-
-
-/* xf86XVClipVideoHelper -
-
- Takes the dst box in standard X BoxRec form (top and left
- edges inclusive, bottom and right exclusive). The new dst
- box is returned. The source boundaries are given (x1, y1
- inclusive, x2, y2 exclusive) and returned are the new source
- boundaries in 16.16 fixed point.
-*/
-
-Bool
-xf86XVClipVideoHelper(
- BoxPtr dst,
- INT32 *xa,
- INT32 *xb,
- INT32 *ya,
- INT32 *yb,
- RegionPtr reg,
- INT32 width,
- INT32 height
-){
- double xsw, xdw, ysw, ydw;
- INT32 delta;
- BoxPtr extents = RegionExtents(reg);
- int diff;
-
- xsw = (*xb - *xa) << 16;
- xdw = dst->x2 - dst->x1;
- ysw = (*yb - *ya) << 16;
- ydw = dst->y2 - dst->y1;
-
- *xa <<= 16; *xb <<= 16;
- *ya <<= 16; *yb <<= 16;
-
- diff = extents->x1 - dst->x1;
- if (diff > 0) {
- dst->x1 = extents->x1;
- *xa += (diff * xsw) / xdw;
- }
- diff = dst->x2 - extents->x2;
- if (diff > 0) {
- dst->x2 = extents->x2;
- *xb -= (diff * xsw) / xdw;
- }
- diff = extents->y1 - dst->y1;
- if (diff > 0) {
- dst->y1 = extents->y1;
- *ya += (diff * ysw) / ydw;
- }
- diff = dst->y2 - extents->y2;
- if (diff > 0) {
- dst->y2 = extents->y2;
- *yb -= (diff * ysw) / ydw;
- }
-
- if (*xa < 0) {
- diff = (((-*xa) * xdw) + xsw - 1) / xsw;
- dst->x1 += diff;
- *xa += (diff * xsw) / xdw;
- }
- delta = *xb - (width << 16);
- if (delta > 0) {
- diff = ((delta * xdw) + xsw - 1) / xsw;
- dst->x2 -= diff;
- *xb -= (diff * xsw) / xdw;
- }
- if (*xa >= *xb) return FALSE;
-
- if (*ya < 0) {
- diff = (((-*ya) * ydw) + ysw - 1) / ysw;
- dst->y1 += diff;
- *ya += (diff * ysw) / ydw;
- }
- delta = *yb - (height << 16);
- if (delta > 0) {
- diff = ((delta * ydw) + ysw - 1) / ysw;
- dst->y2 -= diff;
- *yb -= (diff * ysw) / ydw;
- }
- if (*ya >= *yb) return FALSE;
-
- if ((dst->x1 > extents->x1) || (dst->x2 < extents->x2) ||
- (dst->y1 > extents->y1) || (dst->y2 < extents->y2))
- {
- RegionRec clipReg;
- RegionInit(&clipReg, dst, 1);
- RegionIntersect(reg, reg, &clipReg);
- RegionUninit(&clipReg);
- }
- return TRUE;
-}
-
-void
-xf86XVCopyYUV12ToPacked(
- const void *srcy,
- const void *srcv,
- const void *srcu,
- void *dst,
- int srcPitchy,
- int srcPitchuv,
- int dstPitch,
- int h,
- int w
-){
- CARD32 *Dst;
- const CARD8 *Y, *U, *V;
- int i, j;
-
- w >>= 1;
-
- for (j = 0; j < h; j++) {
- Dst = dst;
- Y = srcy; V = srcv; U = srcu;
- i = w;
- while (i >= 4) {
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
- Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24);
- Dst[1] = Y[2] | (Y[3] << 16) | (U[1] << 8) | (V[1] << 24);
- Dst[2] = Y[4] | (Y[5] << 16) | (U[2] << 8) | (V[2] << 24);
- Dst[3] = Y[6] | (Y[7] << 16) | (U[3] << 8) | (V[3] << 24);
-#else
- /* This assumes a little-endian framebuffer */
- Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0];
- Dst[1] = (Y[2] << 24) | (Y[3] << 8) | (U[1] << 16) | V[1];
- Dst[2] = (Y[4] << 24) | (Y[5] << 8) | (U[2] << 16) | V[2];
- Dst[3] = (Y[6] << 24) | (Y[7] << 8) | (U[3] << 16) | V[3];
-#endif
- Dst += 4; Y += 8; V += 4; U += 4;
- i -= 4;
- }
-
- while (i--) {
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
- Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24);
-#else
- /* This assumes a little-endian framebuffer */
- Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0];
-#endif
- Dst++; Y += 2; V++; U++;
- }
-
- dst = (CARD8 *)dst + dstPitch;
- srcy = (const CARD8 *)srcy + srcPitchy;
- if (j & 1) {
- srcu = (const CARD8 *)srcu + srcPitchuv;
- srcv = (const CARD8 *)srcv + srcPitchuv;
- }
- }
-}
-
-void
-xf86XVCopyPacked(
- const void *src,
- void *dst,
- int srcPitch,
- int dstPitch,
- int h,
- int w
-){
- const CARD32 *Src;
- CARD32 *Dst;
- int i;
-
- w >>= 1;
- while (--h >= 0) {
- do {
- Dst = dst; Src = src;
- i = w;
- while (i >= 4) {
- Dst[0] = Src[0];
- Dst[1] = Src[1];
- Dst[2] = Src[2];
- Dst[3] = Src[3];
- Dst += 4; Src += 4; i -= 4;
- }
- if (!i) break;
- Dst[0] = Src[0];
- if (i == 1) break;
- Dst[1] = Src[1];
- if (i == 2) break;
- Dst[2] = Src[2];
- } while (0);
-
- src = (const CARD8 *)src + srcPitch;
- dst = (CARD8 *)dst + dstPitch;
- }
-}
+/*
+ * XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com)
+ */
+/*
+ * 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).
+ */
+
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+#include "validate.h"
+#include "resource.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvproto.h>
+#include "xvdix.h"
+#include "xvmodproc.h"
+
+#include "xf86xvpriv.h"
+
+
+/* XvScreenRec fields */
+
+static Bool xf86XVCloseScreen(int, ScreenPtr);
+static int xf86XVQueryAdaptors(ScreenPtr, XvAdaptorPtr *, int *);
+
+/* XvAdaptorRec fields */
+
+static int xf86XVAllocatePort(unsigned long, XvPortPtr, XvPortPtr*);
+static int xf86XVFreePort(XvPortPtr);
+static int xf86XVPutVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int xf86XVPutStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int xf86XVGetVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int xf86XVGetStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int xf86XVStopVideo(ClientPtr, XvPortPtr, DrawablePtr);
+static int xf86XVSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32);
+static int xf86XVGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32*);
+static int xf86XVQueryBestSize(ClientPtr, XvPortPtr, CARD8,
+ CARD16, CARD16,CARD16, CARD16,
+ unsigned int*, unsigned int*);
+static int xf86XVPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16,
+ XvImagePtr, unsigned char*, Bool,
+ CARD16, CARD16);
+static int xf86XVQueryImageAttributes(ClientPtr, XvPortPtr, XvImagePtr,
+ CARD16*, CARD16*, int*, int*);
+
+
+/* ScreenRec fields */
+
+static Bool xf86XVDestroyWindow(WindowPtr pWin);
+static void xf86XVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2);
+static void xf86XVPostValidateTree(WindowPtr pWin, WindowPtr pLayerWin, VTKind kind);
+static void xf86XVClipNotify(WindowPtr pWin, int dx, int dy);
+
+#define PostValidateTreeUndefined ((PostValidateTreeProcPtr)-1)
+
+/* ScrnInfoRec functions */
+
+static Bool xf86XVEnterVT(int, int);
+static void xf86XVLeaveVT(int, int);
+static void xf86XVAdjustFrame(int index, int x, int y, int flags);
+static void xf86XVModeSet(ScrnInfoPtr pScrn);
+
+/* misc */
+
+static Bool xf86XVInitAdaptors(ScreenPtr, XF86VideoAdaptorPtr*, int);
+
+
+static DevPrivateKeyRec XF86XVWindowKeyRec;
+#define XF86XVWindowKey (&XF86XVWindowKeyRec)
+
+DevPrivateKey XF86XvScreenKey;
+
+static unsigned long PortResource = 0;
+
+DevPrivateKey (*XvGetScreenKeyProc)(void) = NULL;
+unsigned long (*XvGetRTPortProc)(void) = NULL;
+int (*XvScreenInitProc)(ScreenPtr) = NULL;
+
+#define GET_XV_SCREEN(pScreen) \
+ ((XvScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, XF86XvScreenKey))
+
+#define GET_XF86XV_SCREEN(pScreen) \
+ ((XF86XVScreenPtr)(GET_XV_SCREEN(pScreen)->devPriv.ptr))
+
+#define GET_XF86XV_WINDOW(pWin) \
+ ((XF86XVWindowPtr)dixLookupPrivate(&(pWin)->devPrivates, XF86XVWindowKey))
+
+static xf86XVInitGenericAdaptorPtr *GenDrivers = NULL;
+static int NumGenDrivers = 0;
+
+int
+xf86XVRegisterGenericAdaptorDriver(
+ xf86XVInitGenericAdaptorPtr InitFunc
+){
+ xf86XVInitGenericAdaptorPtr *newdrivers;
+
+ newdrivers = realloc(GenDrivers, sizeof(xf86XVInitGenericAdaptorPtr) *
+ (1 + NumGenDrivers));
+ if (!newdrivers)
+ return 0;
+ GenDrivers = newdrivers;
+
+ GenDrivers[NumGenDrivers++] = InitFunc;
+
+ return 1;
+}
+
+int
+xf86XVListGenericAdaptors(
+ ScrnInfoPtr pScrn,
+ XF86VideoAdaptorPtr **adaptors
+){
+ int i,j,n,num;
+ XF86VideoAdaptorPtr *DrivAdap,*new;
+
+ num = 0;
+ *adaptors = NULL;
+ /*
+ * The v4l driver registers itself first, but can use surfaces registered
+ * by other drivers. So, call the v4l driver last.
+ */
+ for (i = NumGenDrivers; --i >= 0; ) {
+ DrivAdap = NULL;
+ n = (*GenDrivers[i])(pScrn, &DrivAdap);
+ if (0 == n)
+ continue;
+ new = realloc(*adaptors, sizeof(XF86VideoAdaptorPtr) * (num+n));
+ if (NULL == new)
+ continue;
+ *adaptors = new;
+ for (j = 0; j < n; j++, num++)
+ (*adaptors)[num] = DrivAdap[j];
+ }
+ return num;
+}
+
+
+/**************** Offscreen surface stuff *******************/
+
+typedef struct {
+ XF86OffscreenImagePtr images;
+ int num;
+} OffscreenImageRec;
+
+static DevPrivateKeyRec OffscreenPrivateKeyRec;
+#define OffscreenPrivateKey (&OffscreenPrivateKeyRec)
+#define GetOffscreenImage(pScreen) ((OffscreenImageRec *) dixLookupPrivate(&(pScreen)->devPrivates, OffscreenPrivateKey))
+
+Bool
+xf86XVRegisterOffscreenImages(
+ ScreenPtr pScreen,
+ XF86OffscreenImagePtr images,
+ int num
+){
+ OffscreenImageRec *OffscreenImage;
+ /* This function may be called before xf86XVScreenInit, so there's
+ * no better place than this to call dixRegisterPrivateKey to ensure we
+ * have space reserved. After the first call it is a no-op. */
+ if(!dixRegisterPrivateKey(OffscreenPrivateKey, PRIVATE_SCREEN, sizeof(OffscreenImageRec)) ||
+ !(OffscreenImage = GetOffscreenImage(pScreen)))
+ /* Every X.org driver assumes this function always succeeds, so
+ * just die on allocation failure. */
+ FatalError("Could not allocate private storage for XV offscreen images.\n");
+
+ OffscreenImage->num = num;
+ OffscreenImage->images = images;
+ return TRUE;
+}
+
+XF86OffscreenImagePtr
+xf86XVQueryOffscreenImages(
+ ScreenPtr pScreen,
+ int *num
+){
+ OffscreenImageRec *OffscreenImage = GetOffscreenImage(pScreen);
+ *num = OffscreenImage->num;
+ return OffscreenImage->images;
+}
+
+
+XF86VideoAdaptorPtr
+xf86XVAllocateVideoAdaptorRec(ScrnInfoPtr pScrn)
+{
+ return calloc(1, sizeof(XF86VideoAdaptorRec));
+}
+
+void
+xf86XVFreeVideoAdaptorRec(XF86VideoAdaptorPtr ptr)
+{
+ free(ptr);
+}
+
+
+Bool
+xf86XVScreenInit(
+ ScreenPtr pScreen,
+ XF86VideoAdaptorPtr *adaptors,
+ int num
+){
+ ScrnInfoPtr pScrn;
+ XF86XVScreenPtr ScreenPriv;
+ XvScreenPtr pxvs;
+
+ if(num <= 0 ||
+ !XvGetScreenKeyProc || !XvGetRTPortProc || !XvScreenInitProc)
+ return FALSE;
+
+ if(Success != (*XvScreenInitProc)(pScreen)) return FALSE;
+
+ if (!dixRegisterPrivateKey(&XF86XVWindowKeyRec, PRIVATE_WINDOW, 0))
+ return FALSE;
+
+ XF86XvScreenKey = (*XvGetScreenKeyProc)();
+
+ PortResource = (*XvGetRTPortProc)();
+
+ pxvs = GET_XV_SCREEN(pScreen);
+
+ /* Anyone initializing the Xv layer must provide these two.
+ The Xv di layer calls them without even checking if they exist! */
+
+ pxvs->ddCloseScreen = xf86XVCloseScreen;
+ pxvs->ddQueryAdaptors = xf86XVQueryAdaptors;
+
+ /* The Xv di layer provides us with a private hook so that we don't
+ have to allocate our own screen private. They also provide
+ a CloseScreen hook so that we don't have to wrap it. I'm not
+ sure that I appreciate that. */
+
+ ScreenPriv = malloc(sizeof(XF86XVScreenRec));
+ pxvs->devPriv.ptr = (pointer)ScreenPriv;
+
+ if(!ScreenPriv) return FALSE;
+
+ pScrn = xf86Screens[pScreen->myNum];
+
+ ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
+ ScreenPriv->WindowExposures = pScreen->WindowExposures;
+ ScreenPriv->PostValidateTree = PostValidateTreeUndefined;
+ ScreenPriv->ClipNotify = pScreen->ClipNotify;
+ ScreenPriv->EnterVT = pScrn->EnterVT;
+ ScreenPriv->LeaveVT = pScrn->LeaveVT;
+ ScreenPriv->AdjustFrame = pScrn->AdjustFrame;
+ ScreenPriv->ModeSet = pScrn->ModeSet;
+
+ pScreen->DestroyWindow = xf86XVDestroyWindow;
+ pScreen->WindowExposures = xf86XVWindowExposures;
+ pScreen->ClipNotify = xf86XVClipNotify;
+ pScrn->EnterVT = xf86XVEnterVT;
+ pScrn->LeaveVT = xf86XVLeaveVT;
+ if(pScrn->AdjustFrame)
+ pScrn->AdjustFrame = xf86XVAdjustFrame;
+ pScrn->ModeSet = xf86XVModeSet;
+
+ if(!xf86XVInitAdaptors(pScreen, adaptors, num))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)
+{
+ int i;
+
+ free(pAdaptor->name);
+ pAdaptor->name = NULL;
+
+ if(pAdaptor->pEncodings) {
+ XvEncodingPtr pEncode = pAdaptor->pEncodings;
+
+ for(i = 0; i < pAdaptor->nEncodings; i++, pEncode++)
+ free(pEncode->name);
+ free(pAdaptor->pEncodings);
+ pAdaptor->pEncodings = NULL;
+ }
+
+ free(pAdaptor->pFormats);
+ pAdaptor->pFormats = NULL;
+
+ if(pAdaptor->pPorts) {
+ XvPortPtr pPort = pAdaptor->pPorts;
+ XvPortRecPrivatePtr pPriv;
+
+ for(i = 0; i < pAdaptor->nPorts; i++, pPort++) {
+ pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
+ if(pPriv) {
+ if(pPriv->clientClip)
+ RegionDestroy(pPriv->clientClip);
+ if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
+ RegionDestroy(pPriv->pCompositeClip);
+ if (pPriv->ckeyFilled)
+ RegionDestroy(pPriv->ckeyFilled);
+ free(pPriv);
+ }
+ }
+ free(pAdaptor->pPorts);
+ pAdaptor->pPorts = NULL;
+ }
+
+ if(pAdaptor->pAttributes) {
+ XvAttributePtr pAttribute = pAdaptor->pAttributes;
+
+ for(i = 0; i < pAdaptor->nAttributes; i++, pAttribute++)
+ free(pAttribute->name);
+ free(pAdaptor->pAttributes);
+ pAdaptor->pAttributes = NULL;
+ }
+
+ free(pAdaptor->pImages);
+ free(pAdaptor->devPriv.ptr);
+ pAdaptor->pImages = NULL;
+ pAdaptor->devPriv.ptr = NULL;
+}
+
+static Bool
+xf86XVInitAdaptors(
+ ScreenPtr pScreen,
+ XF86VideoAdaptorPtr *infoPtr,
+ int number
+) {
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XF86VideoAdaptorPtr adaptorPtr;
+ XvAdaptorPtr pAdaptor, pa;
+ XvAdaptorRecPrivatePtr adaptorPriv;
+ int na, numAdaptor;
+ XvPortRecPrivatePtr portPriv;
+ XvPortPtr pPort, pp;
+ int numPort;
+ XF86AttributePtr attributePtr;
+ XvAttributePtr pAttribute, pat;
+ XF86VideoFormatPtr formatPtr;
+ XvFormatPtr pFormat, pf;
+ int numFormat, totFormat;
+ XF86VideoEncodingPtr encodingPtr;
+ XvEncodingPtr pEncode, pe;
+ XF86ImagePtr imagePtr;
+ XvImagePtr pImage, pi;
+ int numVisuals;
+ VisualPtr pVisual;
+ int i;
+
+ pxvs->nAdaptors = 0;
+ pxvs->pAdaptors = NULL;
+
+ if(!(pAdaptor = calloc(number, sizeof(XvAdaptorRec))))
+ return FALSE;
+
+ for(pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
+ adaptorPtr = infoPtr[na];
+
+ if(!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
+ !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
+ continue;
+
+ /* client libs expect at least one encoding */
+ if(!adaptorPtr->nEncodings || !adaptorPtr->pEncodings)
+ continue;
+
+ pa->type = adaptorPtr->type;
+
+ if(!adaptorPtr->PutVideo && !adaptorPtr->GetVideo)
+ pa->type &= ~XvVideoMask;
+
+ if(!adaptorPtr->PutStill && !adaptorPtr->GetStill)
+ pa->type &= ~XvStillMask;
+
+ if(!adaptorPtr->PutImage || !adaptorPtr->QueryImageAttributes)
+ pa->type &= ~XvImageMask;
+
+ if(!adaptorPtr->PutVideo && !adaptorPtr->PutImage &&
+ !adaptorPtr->PutStill)
+ pa->type &= ~XvInputMask;
+
+ if(!adaptorPtr->GetVideo && !adaptorPtr->GetStill)
+ pa->type &= ~XvOutputMask;
+
+ if(!(adaptorPtr->type & (XvPixmapMask | XvWindowMask)))
+ continue;
+ if(!(adaptorPtr->type & (XvImageMask | XvVideoMask | XvStillMask)))
+ continue;
+
+ pa->pScreen = pScreen;
+ pa->ddAllocatePort = xf86XVAllocatePort;
+ pa->ddFreePort = xf86XVFreePort;
+ pa->ddPutVideo = xf86XVPutVideo;
+ pa->ddPutStill = xf86XVPutStill;
+ pa->ddGetVideo = xf86XVGetVideo;
+ pa->ddGetStill = xf86XVGetStill;
+ pa->ddStopVideo = xf86XVStopVideo;
+ pa->ddPutImage = xf86XVPutImage;
+ pa->ddSetPortAttribute = xf86XVSetPortAttribute;
+ pa->ddGetPortAttribute = xf86XVGetPortAttribute;
+ pa->ddQueryBestSize = xf86XVQueryBestSize;
+ pa->ddQueryImageAttributes = xf86XVQueryImageAttributes;
+ pa->name = strdup(adaptorPtr->name);
+
+ if(adaptorPtr->nEncodings &&
+ (pEncode = calloc(adaptorPtr->nEncodings, sizeof(XvEncodingRec)))) {
+
+ for(pe = pEncode, encodingPtr = adaptorPtr->pEncodings, i = 0;
+ i < adaptorPtr->nEncodings; pe++, i++, encodingPtr++)
+ {
+ pe->id = encodingPtr->id;
+ pe->pScreen = pScreen;
+ pe->name = strdup(encodingPtr->name);
+ pe->width = encodingPtr->width;
+ pe->height = encodingPtr->height;
+ pe->rate.numerator = encodingPtr->rate.numerator;
+ pe->rate.denominator = encodingPtr->rate.denominator;
+ }
+ pa->nEncodings = adaptorPtr->nEncodings;
+ pa->pEncodings = pEncode;
+ }
+
+ if(adaptorPtr->nImages &&
+ (pImage = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
+
+ for(i = 0, pi = pImage, imagePtr = adaptorPtr->pImages;
+ i < adaptorPtr->nImages; i++, pi++, imagePtr++)
+ {
+ pi->id = imagePtr->id;
+ pi->type = imagePtr->type;
+ pi->byte_order = imagePtr->byte_order;
+ memcpy(pi->guid, imagePtr->guid, 16);
+ pi->bits_per_pixel = imagePtr->bits_per_pixel;
+ pi->format = imagePtr->format;
+ pi->num_planes = imagePtr->num_planes;
+ pi->depth = imagePtr->depth;
+ pi->red_mask = imagePtr->red_mask;
+ pi->green_mask = imagePtr->green_mask;
+ pi->blue_mask = imagePtr->blue_mask;
+ pi->y_sample_bits = imagePtr->y_sample_bits;
+ pi->u_sample_bits = imagePtr->u_sample_bits;
+ pi->v_sample_bits = imagePtr->v_sample_bits;
+ pi->horz_y_period = imagePtr->horz_y_period;
+ pi->horz_u_period = imagePtr->horz_u_period;
+ pi->horz_v_period = imagePtr->horz_v_period;
+ pi->vert_y_period = imagePtr->vert_y_period;
+ pi->vert_u_period = imagePtr->vert_u_period;
+ pi->vert_v_period = imagePtr->vert_v_period;
+ memcpy(pi->component_order, imagePtr->component_order, 32);
+ pi->scanline_order = imagePtr->scanline_order;
+ }
+ pa->nImages = adaptorPtr->nImages;
+ pa->pImages = pImage;
+ }
+
+ if(adaptorPtr->nAttributes &&
+ (pAttribute = calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec))))
+ {
+ for(pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i = 0;
+ i < adaptorPtr->nAttributes; pat++, i++, attributePtr++)
+ {
+ pat->flags = attributePtr->flags;
+ pat->min_value = attributePtr->min_value;
+ pat->max_value = attributePtr->max_value;
+ pat->name = strdup(attributePtr->name);
+ }
+ pa->nAttributes = adaptorPtr->nAttributes;
+ pa->pAttributes = pAttribute;
+ }
+
+
+ totFormat = adaptorPtr->nFormats;
+
+ if(!(pFormat = calloc(totFormat, sizeof(XvFormatRec)))) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+ for(pf = pFormat, i = 0, numFormat = 0, formatPtr = adaptorPtr->pFormats;
+ i < adaptorPtr->nFormats; i++, formatPtr++)
+ {
+ numVisuals = pScreen->numVisuals;
+ pVisual = pScreen->visuals;
+
+ while(numVisuals--) {
+ if((pVisual->class == formatPtr->class) &&
+ (pVisual->nplanes == formatPtr->depth)) {
+
+ if(numFormat >= totFormat) {
+ void *moreSpace;
+ totFormat *= 2;
+ moreSpace = realloc(pFormat,
+ totFormat * sizeof(XvFormatRec));
+ if(!moreSpace) break;
+ pFormat = moreSpace;
+ pf = pFormat + numFormat;
+ }
+
+ pf->visual = pVisual->vid;
+ pf->depth = formatPtr->depth;
+
+ pf++;
+ numFormat++;
+ }
+ pVisual++;
+ }
+ }
+ pa->nFormats = numFormat;
+ pa->pFormats = pFormat;
+ if(!numFormat) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+
+ if(!(adaptorPriv = calloc(1, sizeof(XvAdaptorRecPrivate)))) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+
+ adaptorPriv->flags = adaptorPtr->flags;
+ adaptorPriv->PutVideo = adaptorPtr->PutVideo;
+ adaptorPriv->PutStill = adaptorPtr->PutStill;
+ adaptorPriv->GetVideo = adaptorPtr->GetVideo;
+ adaptorPriv->GetStill = adaptorPtr->GetStill;
+ adaptorPriv->StopVideo = adaptorPtr->StopVideo;
+ adaptorPriv->SetPortAttribute = adaptorPtr->SetPortAttribute;
+ adaptorPriv->GetPortAttribute = adaptorPtr->GetPortAttribute;
+ adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize;
+ adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes;
+ adaptorPriv->PutImage = adaptorPtr->PutImage;
+ adaptorPriv->ReputImage = adaptorPtr->ReputImage; /* image/still */
+
+ pa->devPriv.ptr = (pointer)adaptorPriv;
+
+ if(!(pPort = calloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+ for(pp = pPort, i = 0, numPort = 0;
+ i < adaptorPtr->nPorts; i++) {
+
+ if(!(pp->id = FakeClientID(0)))
+ continue;
+
+ if(!(portPriv = calloc(1, sizeof(XvPortRecPrivate))))
+ continue;
+
+ if(!AddResource(pp->id, PortResource, pp)) {
+ free(portPriv);
+ continue;
+ }
+
+ pp->pAdaptor = pa;
+ pp->pNotify = (XvPortNotifyPtr)NULL;
+ pp->pDraw = (DrawablePtr)NULL;
+ pp->client = (ClientPtr)NULL;
+ pp->grab.client = (ClientPtr)NULL;
+ pp->time = currentTime;
+ pp->devPriv.ptr = portPriv;
+
+ portPriv->pScrn = pScrn;
+ portPriv->AdaptorRec = adaptorPriv;
+ portPriv->DevPriv.ptr = adaptorPtr->pPortPrivates[i].ptr;
+
+ pp++;
+ numPort++;
+ }
+ pa->nPorts = numPort;
+ pa->pPorts = pPort;
+ if(!numPort) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+
+ pa->base_id = pPort->id;
+
+ pa++;
+ numAdaptor++;
+ }
+
+ if(numAdaptor) {
+ pxvs->nAdaptors = numAdaptor;
+ pxvs->pAdaptors = pAdaptor;
+ } else {
+ free(pAdaptor);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Video should be clipped to the intersection of the window cliplist
+ and the client cliplist specified in the GC for which the video was
+ initialized. When we need to reclip a window, the GC that started
+ the video may not even be around anymore. That's why we save the
+ client clip from the GC when the video is initialized. We then
+ use xf86XVUpdateCompositeClip to calculate the new composite clip
+ when we need it. This is different from what DEC did. They saved
+ the GC and used it's clip list when they needed to reclip the window,
+ even if the client clip was different from the one the video was
+ initialized with. If the original GC was destroyed, they had to stop
+ the video. I like the new method better (MArk).
+
+ This function only works for windows. Will need to rewrite when
+ (if) we support pixmap rendering.
+*/
+
+static void
+xf86XVUpdateCompositeClip(XvPortRecPrivatePtr portPriv)
+{
+ RegionPtr pregWin, pCompositeClip;
+ WindowPtr pWin;
+ Bool freeCompClip = FALSE;
+
+ if(portPriv->pCompositeClip)
+ return;
+
+ pWin = (WindowPtr)portPriv->pDraw;
+
+ /* get window clip list */
+ if(portPriv->subWindowMode == IncludeInferiors) {
+ pregWin = NotClippedByChildren(pWin);
+ freeCompClip = TRUE;
+ } else
+ pregWin = &pWin->clipList;
+
+ if(!portPriv->clientClip) {
+ portPriv->pCompositeClip = pregWin;
+ portPriv->FreeCompositeClip = freeCompClip;
+ return;
+ }
+
+ pCompositeClip = RegionCreate(NullBox, 1);
+ RegionCopy(pCompositeClip, portPriv->clientClip);
+ RegionTranslate(pCompositeClip,
+ portPriv->pDraw->x, portPriv->pDraw->y);
+ RegionIntersect(pCompositeClip, pregWin, pCompositeClip);
+
+ portPriv->pCompositeClip = pCompositeClip;
+ portPriv->FreeCompositeClip = TRUE;
+
+ if(freeCompClip) {
+ RegionDestroy(pregWin);
+ }
+}
+
+/* Save the current clientClip and update the CompositeClip whenever
+ we have a fresh GC */
+
+static void
+xf86XVCopyClip(
+ XvPortRecPrivatePtr portPriv,
+ GCPtr pGC
+){
+ /* copy the new clip if it exists */
+ if((pGC->clientClipType == CT_REGION) && pGC->clientClip) {
+ if(!portPriv->clientClip)
+ portPriv->clientClip = RegionCreate(NullBox, 1);
+ /* Note: this is in window coordinates */
+ RegionCopy(portPriv->clientClip, pGC->clientClip);
+ RegionTranslate(portPriv->clientClip,
+ pGC->clipOrg.x, pGC->clipOrg.y);
+ } else if(portPriv->clientClip) { /* free the old clientClip */
+ RegionDestroy(portPriv->clientClip);
+ portPriv->clientClip = NULL;
+ }
+
+ /* get rid of the old clip list */
+ if(portPriv->pCompositeClip && portPriv->FreeCompositeClip) {
+ RegionDestroy(portPriv->pCompositeClip);
+ }
+
+ portPriv->pCompositeClip = pGC->pCompositeClip;
+ portPriv->FreeCompositeClip = FALSE;
+ portPriv->subWindowMode = pGC->subWindowMode;
+}
+
+static void
+xf86XVCopyCompositeClip(XvPortRecPrivatePtr portPriv,
+ GCPtr pGC,
+ DrawablePtr pDraw)
+{
+ if (!portPriv->clientClip)
+ portPriv->clientClip = RegionCreate(NullBox, 1);
+ /* Keep the original GC composite clip around for ReputImage */
+ RegionCopy(portPriv->clientClip, pGC->pCompositeClip);
+ RegionTranslate(portPriv->clientClip,
+ -pDraw->x, -pDraw->y);
+
+ /* get rid of the old clip list */
+ if (portPriv->pCompositeClip && portPriv->FreeCompositeClip)
+ RegionDestroy(portPriv->pCompositeClip);
+
+ portPriv->pCompositeClip = pGC->pCompositeClip;
+ portPriv->FreeCompositeClip = FALSE;
+ portPriv->subWindowMode = pGC->subWindowMode;
+}
+
+static int
+xf86XVRegetVideo(XvPortRecPrivatePtr portPriv)
+{
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ xf86XVUpdateCompositeClip(portPriv);
+
+ /* translate the video region to the screen */
+ WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
+ WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
+ WinBox.x2 = WinBox.x1 + portPriv->drw_w;
+ WinBox.y2 = WinBox.y1 + portPriv->drw_h;
+
+ /* clip to the window composite clip */
+ RegionInit(&WinRegion, &WinBox, 1);
+ RegionNull(&ClipRegion);
+ RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
+
+ /* that's all if it's totally obscured */
+ if(!RegionNotEmpty(&ClipRegion)) {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->GetVideo)(portPriv->pScrn,
+ portPriv->vid_x, portPriv->vid_y,
+ WinBox.x1, WinBox.y1,
+ portPriv->vid_w, portPriv->vid_h,
+ portPriv->drw_w, portPriv->drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ portPriv->pDraw);
+
+ if(ret == Success)
+ portPriv->isOn = XV_ON;
+
+CLIP_VIDEO_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ /* This clip was copied and only good for one shot */
+ if(!portPriv->FreeCompositeClip)
+ portPriv->pCompositeClip = NULL;
+
+ RegionUninit(&WinRegion);
+ RegionUninit(&ClipRegion);
+
+ return ret;
+}
+
+
+static int
+xf86XVReputVideo(XvPortRecPrivatePtr portPriv)
+{
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ xf86XVUpdateCompositeClip(portPriv);
+
+ /* translate the video region to the screen */
+ WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
+ WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
+ WinBox.x2 = WinBox.x1 + portPriv->drw_w;
+ WinBox.y2 = WinBox.y1 + portPriv->drw_h;
+
+ /* clip to the window composite clip */
+ RegionInit(&WinRegion, &WinBox, 1);
+ RegionNull(&ClipRegion);
+ RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
+
+ /* clip and translate to the viewport */
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = portPriv->pScrn->frameX0;
+ VPBox.y1 = portPriv->pScrn->frameY0;
+ VPBox.x2 = portPriv->pScrn->frameX1 + 1;
+ VPBox.y2 = portPriv->pScrn->frameY1 + 1;
+
+ RegionInit(&VPReg, &VPBox, 1);
+ RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
+ RegionUninit(&VPReg);
+ }
+
+ /* that's all if it's totally obscured */
+ if(!RegionNotEmpty(&ClipRegion)) {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+
+ /* bailout if we have to clip but the hardware doesn't support it */
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = RegionRects(&ClipRegion);
+ if( (RegionNumRects(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->PutVideo)(portPriv->pScrn,
+ portPriv->vid_x, portPriv->vid_y,
+ WinBox.x1, WinBox.y1,
+ portPriv->vid_w, portPriv->vid_h,
+ portPriv->drw_w, portPriv->drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ portPriv->pDraw);
+
+ if(ret == Success) portPriv->isOn = XV_ON;
+
+CLIP_VIDEO_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ /* This clip was copied and only good for one shot */
+ if(!portPriv->FreeCompositeClip)
+ portPriv->pCompositeClip = NULL;
+
+ RegionUninit(&WinRegion);
+ RegionUninit(&ClipRegion);
+
+ return ret;
+}
+
+/* Reput image/still */
+static int
+xf86XVReputImage(XvPortRecPrivatePtr portPriv)
+{
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ xf86XVUpdateCompositeClip(portPriv);
+
+ /* the clip can get smaller over time */
+ RegionCopy(portPriv->clientClip, portPriv->pCompositeClip);
+ RegionTranslate(portPriv->clientClip,
+ -portPriv->pDraw->x, -portPriv->pDraw->y);
+
+ /* translate the video region to the screen */
+ WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
+ WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
+ WinBox.x2 = WinBox.x1 + portPriv->drw_w;
+ WinBox.y2 = WinBox.y1 + portPriv->drw_h;
+
+ /* clip to the window composite clip */
+ RegionInit(&WinRegion, &WinBox, 1);
+ RegionNull(&ClipRegion);
+ RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
+
+ /* clip and translate to the viewport */
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = portPriv->pScrn->frameX0;
+ VPBox.y1 = portPriv->pScrn->frameY0;
+ VPBox.x2 = portPriv->pScrn->frameX1 + 1;
+ VPBox.y2 = portPriv->pScrn->frameY1 + 1;
+
+ RegionInit(&VPReg, &VPBox, 1);
+ RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
+ RegionUninit(&VPReg);
+ }
+
+ /* that's all if it's totally obscured */
+ if(!RegionNotEmpty(&ClipRegion)) {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+
+ /* bailout if we have to clip but the hardware doesn't support it */
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = RegionRects(&ClipRegion);
+ if( (RegionNumRects(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->pScrn,
+ portPriv->vid_x, portPriv->vid_y,
+ WinBox.x1, WinBox.y1,
+ portPriv->vid_w, portPriv->vid_h,
+ portPriv->drw_w, portPriv->drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ portPriv->pDraw);
+
+ portPriv->isOn = (ret == Success) ? XV_ON : XV_OFF;
+
+CLIP_VIDEO_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ /* This clip was copied and only good for one shot */
+ if(!portPriv->FreeCompositeClip)
+ portPriv->pCompositeClip = NULL;
+
+ RegionUninit(&WinRegion);
+ RegionUninit(&ClipRegion);
+
+ return ret;
+}
+
+
+static int
+xf86XVReputAllVideo(WindowPtr pWin, pointer data)
+{
+ XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
+
+ while(WinPriv) {
+ if(WinPriv->PortRec->type == XvInputMask)
+ xf86XVReputVideo(WinPriv->PortRec);
+ else
+ xf86XVRegetVideo(WinPriv->PortRec);
+ WinPriv = WinPriv->next;
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static int
+xf86XVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
+{
+ XF86XVWindowPtr winPriv, PrivRoot;
+
+ winPriv = PrivRoot = GET_XF86XV_WINDOW(pWin);
+
+ /* Enlist our port in the window private */
+ while(winPriv) {
+ if(winPriv->PortRec == portPriv) /* we're already listed */
+ break;
+ winPriv = winPriv->next;
+ }
+
+ if(!winPriv) {
+ winPriv = calloc(1, sizeof(XF86XVWindowRec));
+ if(!winPriv) return BadAlloc;
+ winPriv->PortRec = portPriv;
+ winPriv->next = PrivRoot;
+ dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, winPriv);
+ }
+
+ portPriv->pDraw = (DrawablePtr)pWin;
+
+ return Success;
+}
+
+
+static void
+xf86XVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
+{
+ XF86XVWindowPtr winPriv, prevPriv = NULL;
+ winPriv = GET_XF86XV_WINDOW(pWin);
+
+ while(winPriv) {
+ if(winPriv->PortRec == portPriv) {
+ if(prevPriv)
+ prevPriv->next = winPriv->next;
+ else
+ dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
+ winPriv->next);
+ free(winPriv);
+ break;
+ }
+ prevPriv = winPriv;
+ winPriv = winPriv->next;
+ }
+ portPriv->pDraw = NULL;
+ if (portPriv->ckeyFilled) {
+ RegionDestroy(portPriv->ckeyFilled);
+ portPriv->ckeyFilled = NULL;
+ }
+ portPriv->clipChanged = FALSE;
+}
+
+static void
+xf86XVReputOrStopPort(XvPortRecPrivatePtr pPriv,
+ WindowPtr pWin,
+ Bool visible)
+{
+ if (!visible) {
+ if (pPriv->isOn == XV_ON) {
+ (*pPriv->AdaptorRec->StopVideo)(pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
+ pPriv->isOn = XV_PENDING;
+ }
+
+ if (!pPriv->type) /* overlaid still/image*/
+ xf86XVRemovePortFromWindow(pWin, pPriv);
+
+ return;
+ }
+
+ switch (pPriv->type) {
+ case XvInputMask:
+ xf86XVReputVideo(pPriv);
+ break;
+ case XvOutputMask:
+ xf86XVRegetVideo(pPriv);
+ break;
+ default: /* overlaid still/image*/
+ if (pPriv->AdaptorRec->ReputImage)
+ xf86XVReputImage(pPriv);
+ break;
+ }
+}
+
+static void
+xf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn, Bool onlyChanged)
+{
+ ScreenPtr pScreen = pScrn->pScreen;
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+ XvAdaptorPtr pa;
+ int c, i;
+
+ for (c = pxvs->nAdaptors, pa = pxvs->pAdaptors; c > 0; c--, pa++) {
+ XvPortPtr pPort = pa->pPorts;
+
+ for (i = pa->nPorts; i > 0; i--, pPort++) {
+ XvPortRecPrivatePtr pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
+ WindowPtr pWin = (WindowPtr)pPriv->pDraw;
+ Bool visible;
+
+ if (pPriv->isOn == XV_OFF || !pWin)
+ continue;
+
+ if (onlyChanged && !pPriv->clipChanged)
+ continue;
+
+ visible = pWin->visibility == VisibilityUnobscured ||
+ pWin->visibility == VisibilityPartiallyObscured;
+
+ /*
+ * Stop and remove still/images if
+ * ReputImage isn't supported.
+ */
+ if (!pPriv->type && !pPriv->AdaptorRec->ReputImage)
+ visible = FALSE;
+
+ xf86XVReputOrStopPort(pPriv, pWin, visible);
+
+ pPriv->clipChanged = FALSE;
+ }
+ }
+}
+
+/**** ScreenRec fields ****/
+
+static Bool
+xf86XVDestroyWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XF86XVWindowPtr tmp, WinPriv = GET_XF86XV_WINDOW(pWin);
+ int ret;
+
+ while(WinPriv) {
+ XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
+
+ if(pPriv->isOn > XV_OFF) {
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->pScrn, pPriv->DevPriv.ptr, TRUE);
+ pPriv->isOn = XV_OFF;
+ }
+
+ pPriv->pDraw = NULL;
+ tmp = WinPriv;
+ WinPriv = WinPriv->next;
+ free(tmp);
+ }
+
+ dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, NULL);
+
+ pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
+ ret = (*pScreen->DestroyWindow)(pWin);
+ pScreen->DestroyWindow = xf86XVDestroyWindow;
+
+ return ret;
+}
+
+static void
+xf86XVPostValidateTree(WindowPtr pWin, WindowPtr pLayerWin, VTKind kind)
+{
+ ScreenPtr pScreen;
+ XF86XVScreenPtr ScreenPriv;
+ ScrnInfoPtr pScrn;
+
+ if (pWin)
+ pScreen = pWin->drawable.pScreen;
+ else
+ pScreen = pLayerWin->drawable.pScreen;
+
+ ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ pScrn = xf86Screens[pScreen->myNum];
+
+ xf86XVReputOrStopAllPorts(pScrn, TRUE);
+
+ pScreen->PostValidateTree = ScreenPriv->PostValidateTree;
+ if (pScreen->PostValidateTree) {
+ (*pScreen->PostValidateTree)(pWin, pLayerWin, kind);
+ }
+ ScreenPriv->PostValidateTree = PostValidateTreeUndefined;
+}
+
+static void
+xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
+ XvPortRecPrivatePtr pPriv;
+ Bool AreasExposed;
+
+ AreasExposed = (WinPriv && reg1 && RegionNotEmpty(reg1));
+
+ pScreen->WindowExposures = ScreenPriv->WindowExposures;
+ (*pScreen->WindowExposures)(pWin, reg1, reg2);
+ pScreen->WindowExposures = xf86XVWindowExposures;
+
+ /* filter out XClearWindow/Area */
+ if (!pWin->valdata) return;
+
+ while(WinPriv) {
+ Bool visible = TRUE;
+
+ pPriv = WinPriv->PortRec;
+
+ /*
+ * Stop and remove still/images if areas were exposed and
+ * ReputImage isn't supported.
+ */
+ if (!pPriv->type && !pPriv->AdaptorRec->ReputImage)
+ visible = !AreasExposed;
+
+ /*
+ * Subtract exposed areas from overlaid image to match textured video
+ * behavior.
+ */
+ if (!pPriv->type && pPriv->clientClip)
+ RegionSubtract(pPriv->clientClip, pPriv->clientClip, reg1);
+
+ if (visible && pPriv->ckeyFilled) {
+ RegionRec tmp;
+ RegionNull(&tmp);
+ RegionCopy(&tmp, reg1);
+ RegionTranslate(&tmp, pWin->drawable.x, pWin->drawable.y);
+ RegionSubtract(pPriv->ckeyFilled, pPriv->ckeyFilled, &tmp);
+ }
+
+ WinPriv = WinPriv->next;
+ xf86XVReputOrStopPort(pPriv, pWin, visible);
+
+ pPriv->clipChanged = FALSE;
+ }
+}
+
+static void
+xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
+ XvPortRecPrivatePtr pPriv;
+
+ while(WinPriv) {
+ pPriv = WinPriv->PortRec;
+
+ if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
+ RegionDestroy(pPriv->pCompositeClip);
+
+ pPriv->pCompositeClip = NULL;
+
+ if (pPriv->AdaptorRec->ClipNotify)
+ (*pPriv->AdaptorRec->ClipNotify)(pPriv->pScrn, pPriv->DevPriv.ptr,
+ pWin, dx, dy);
+
+ pPriv->clipChanged = TRUE;
+
+ if (ScreenPriv->PostValidateTree == PostValidateTreeUndefined) {
+ ScreenPriv->PostValidateTree = pScreen->PostValidateTree;
+ pScreen->PostValidateTree = xf86XVPostValidateTree;
+ }
+
+ WinPriv = WinPriv->next;
+ }
+
+ if(ScreenPriv->ClipNotify) {
+ pScreen->ClipNotify = ScreenPriv->ClipNotify;
+ (*pScreen->ClipNotify)(pWin, dx, dy);
+ pScreen->ClipNotify = xf86XVClipNotify;
+ }
+}
+
+
+
+/**** Required XvScreenRec fields ****/
+
+static Bool
+xf86XVCloseScreen(int i, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XvAdaptorPtr pa;
+ int c;
+
+ if(!ScreenPriv) return TRUE;
+
+ pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
+ pScreen->WindowExposures = ScreenPriv->WindowExposures;
+ pScreen->ClipNotify = ScreenPriv->ClipNotify;
+
+ pScrn->EnterVT = ScreenPriv->EnterVT;
+ pScrn->LeaveVT = ScreenPriv->LeaveVT;
+ pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
+ pScrn->ModeSet = ScreenPriv->ModeSet;
+
+ for(c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) {
+ xf86XVFreeAdaptor(pa);
+ }
+
+ free(pxvs->pAdaptors);
+ free(ScreenPriv);
+ return TRUE;
+}
+
+
+static int
+xf86XVQueryAdaptors(
+ ScreenPtr pScreen,
+ XvAdaptorPtr *p_pAdaptors,
+ int *p_nAdaptors
+){
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+
+ *p_nAdaptors = pxvs->nAdaptors;
+ *p_pAdaptors = pxvs->pAdaptors;
+
+ return Success;
+}
+
+
+/**** ScrnInfoRec fields ****/
+
+static Bool
+xf86XVEnterVT(int index, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ Bool ret;
+
+ pScrn->EnterVT = ScreenPriv->EnterVT;
+ ret = (*ScreenPriv->EnterVT)(index, flags);
+ ScreenPriv->EnterVT = pScrn->EnterVT;
+ pScrn->EnterVT = xf86XVEnterVT;
+
+ if(ret) WalkTree(pScreen, xf86XVReputAllVideo, 0);
+
+ return ret;
+}
+
+static void
+xf86XVLeaveVT(int index, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XvAdaptorPtr pAdaptor;
+ XvPortPtr pPort;
+ XvPortRecPrivatePtr pPriv;
+ int i, j;
+
+ for(i = 0; i < pxvs->nAdaptors; i++) {
+ pAdaptor = &pxvs->pAdaptors[i];
+ for(j = 0; j < pAdaptor->nPorts; j++) {
+ pPort = &pAdaptor->pPorts[j];
+ pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
+ if(pPriv->isOn > XV_OFF) {
+
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->pScrn, pPriv->DevPriv.ptr, TRUE);
+ pPriv->isOn = XV_OFF;
+
+ if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
+ RegionDestroy(pPriv->pCompositeClip);
+
+ pPriv->pCompositeClip = NULL;
+
+ if(!pPriv->type && pPriv->pDraw) { /* still */
+ xf86XVRemovePortFromWindow((WindowPtr)pPriv->pDraw, pPriv);
+ }
+ }
+ }
+ }
+
+ pScrn->LeaveVT = ScreenPriv->LeaveVT;
+ (*ScreenPriv->LeaveVT)(index, flags);
+ ScreenPriv->LeaveVT = pScrn->LeaveVT;
+ pScrn->LeaveVT = xf86XVLeaveVT;
+}
+
+static void
+xf86XVAdjustFrame(int index, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ ScreenPtr pScreen = pScrn->pScreen;
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+
+ if(ScreenPriv->AdjustFrame) {
+ pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
+ (*pScrn->AdjustFrame)(index, x, y, flags);
+ pScrn->AdjustFrame = xf86XVAdjustFrame;
+ }
+
+ xf86XVReputOrStopAllPorts(pScrn, FALSE);
+}
+
+static void
+xf86XVModeSet(ScrnInfoPtr pScrn)
+{
+ ScreenPtr pScreen = pScrn->pScreen;
+ XF86XVScreenPtr ScreenPriv;
+
+ /* Can be called before pScrn->pScreen is set */
+ if (!pScreen)
+ return;
+
+ ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+
+ if (ScreenPriv->ModeSet) {
+ pScrn->ModeSet = ScreenPriv->ModeSet;
+ (*pScrn->ModeSet)(pScrn);
+ pScrn->ModeSet = xf86XVModeSet;
+ }
+
+ xf86XVReputOrStopAllPorts(pScrn, FALSE);
+}
+
+/**** XvAdaptorRec fields ****/
+
+static int
+xf86XVAllocatePort(
+ unsigned long port,
+ XvPortPtr pPort,
+ XvPortPtr *ppPort
+){
+ *ppPort = pPort;
+ return Success;
+}
+
+
+
+static int
+xf86XVFreePort(XvPortPtr pPort)
+{
+ return Success;
+}
+
+
+static int
+xf86XVPutVideo(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ int result;
+
+ /* No dumping video to pixmaps... For now anyhow */
+ if(pDraw->type != DRAWABLE_WINDOW) {
+ pPort->pDraw = (DrawablePtr)NULL;
+ return BadAlloc;
+ }
+
+ /* If we are changing windows, unregister our port in the old window */
+ if(portPriv->pDraw && (portPriv->pDraw != pDraw))
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+
+ /* Register our port with the new window */
+ result = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ if(result != Success) return result;
+
+ portPriv->type = XvInputMask;
+
+ /* save a copy of these parameters */
+ portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
+ portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+
+ /* make sure we have the most recent copy of the clientClip */
+ xf86XVCopyClip(portPriv, pGC);
+
+ /* To indicate to the DI layer that we were successful */
+ pPort->pDraw = pDraw;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ return(xf86XVReputVideo(portPriv));
+}
+
+static int
+xf86XVPutStill(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ if (pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ WinBox.x1 = pDraw->x + drw_x;
+ WinBox.y1 = pDraw->y + drw_y;
+ WinBox.x2 = WinBox.x1 + drw_w;
+ WinBox.y2 = WinBox.y1 + drw_h;
+
+ xf86XVCopyCompositeClip(portPriv, pGC, pDraw);
+
+ RegionInit(&WinRegion, &WinBox, 1);
+ RegionNull(&ClipRegion);
+ RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
+
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = portPriv->pScrn->frameX0;
+ VPBox.y1 = portPriv->pScrn->frameY0;
+ VPBox.x2 = portPriv->pScrn->frameX1 + 1;
+ VPBox.y2 = portPriv->pScrn->frameY1 + 1;
+
+ RegionInit(&VPReg, &VPBox, 1);
+ RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
+ RegionUninit(&VPReg);
+ }
+
+ if(portPriv->pDraw) {
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+ }
+
+ if(!RegionNotEmpty(&ClipRegion)) {
+ clippedAway = TRUE;
+ goto PUT_STILL_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = RegionRects(&ClipRegion);
+ if( (RegionNumRects(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto PUT_STILL_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->PutStill)(portPriv->pScrn,
+ vid_x, vid_y, WinBox.x1, WinBox.y1,
+ vid_w, vid_h, drw_w, drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ pDraw);
+
+ if((ret == Success) &&
+ (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_STILLS)) {
+
+ xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ portPriv->isOn = XV_ON;
+ portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
+ portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+ portPriv->type = 0; /* no mask means it's transient and should
+ not be reput once it's removed */
+ pPort->pDraw = pDraw; /* make sure we can get stop requests */
+ }
+
+PUT_STILL_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ /* This clip was copied and only good for one shot */
+ if(!portPriv->FreeCompositeClip)
+ portPriv->pCompositeClip = NULL;
+
+ RegionUninit(&WinRegion);
+ RegionUninit(&ClipRegion);
+
+ return ret;
+}
+
+static int
+xf86XVGetVideo(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ int result;
+
+ /* No pixmaps... For now anyhow */
+ if(pDraw->type != DRAWABLE_WINDOW) {
+ pPort->pDraw = (DrawablePtr)NULL;
+ return BadAlloc;
+ }
+
+ /* If we are changing windows, unregister our port in the old window */
+ if(portPriv->pDraw && (portPriv->pDraw != pDraw))
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+
+ /* Register our port with the new window */
+ result = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ if(result != Success) return result;
+
+ portPriv->type = XvOutputMask;
+
+ /* save a copy of these parameters */
+ portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
+ portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+
+ /* make sure we have the most recent copy of the clientClip */
+ xf86XVCopyClip(portPriv, pGC);
+
+ /* To indicate to the DI layer that we were successful */
+ pPort->pDraw = pDraw;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ return(xf86XVRegetVideo(portPriv));
+}
+
+static int
+xf86XVGetStill(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ if (pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ WinBox.x1 = pDraw->x + drw_x;
+ WinBox.y1 = pDraw->y + drw_y;
+ WinBox.x2 = WinBox.x1 + drw_w;
+ WinBox.y2 = WinBox.y1 + drw_h;
+
+ RegionInit(&WinRegion, &WinBox, 1);
+ RegionNull(&ClipRegion);
+ RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
+
+ if(portPriv->pDraw) {
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+ }
+
+ if(!RegionNotEmpty(&ClipRegion)) {
+ clippedAway = TRUE;
+ goto GET_STILL_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->GetStill)(portPriv->pScrn,
+ vid_x, vid_y, WinBox.x1, WinBox.y1,
+ vid_w, vid_h, drw_w, drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ pDraw);
+
+GET_STILL_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ RegionUninit(&WinRegion);
+ RegionUninit(&ClipRegion);
+
+ return ret;
+}
+
+
+
+static int
+xf86XVStopVideo(
+ ClientPtr client,
+ XvPortPtr pPort,
+ DrawablePtr pDraw
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ if(pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ xf86XVRemovePortFromWindow((WindowPtr)pDraw, portPriv);
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ /* Must free resources. */
+
+ if(portPriv->isOn > XV_OFF) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, TRUE);
+ portPriv->isOn = XV_OFF;
+ }
+
+ return Success;
+}
+
+static int
+xf86XVSetPortAttribute(
+ ClientPtr client,
+ XvPortPtr pPort,
+ Atom attribute,
+ INT32 value
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ return((*portPriv->AdaptorRec->SetPortAttribute)(portPriv->pScrn,
+ attribute, value, portPriv->DevPriv.ptr));
+}
+
+
+static int
+xf86XVGetPortAttribute(
+ ClientPtr client,
+ XvPortPtr pPort,
+ Atom attribute,
+ INT32 *p_value
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ return((*portPriv->AdaptorRec->GetPortAttribute)(portPriv->pScrn,
+ attribute, p_value, portPriv->DevPriv.ptr));
+}
+
+
+
+static int
+xf86XVQueryBestSize(
+ ClientPtr client,
+ XvPortPtr pPort,
+ CARD8 motion,
+ CARD16 vid_w, CARD16 vid_h,
+ CARD16 drw_w, CARD16 drw_h,
+ unsigned int *p_w, unsigned int *p_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ (*portPriv->AdaptorRec->QueryBestSize)(portPriv->pScrn,
+ (Bool)motion, vid_w, vid_h, drw_w, drw_h,
+ p_w, p_h, portPriv->DevPriv.ptr);
+
+ return Success;
+}
+
+
+static int
+xf86XVPutImage(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 src_x, INT16 src_y,
+ CARD16 src_w, CARD16 src_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h,
+ XvImagePtr format,
+ unsigned char* data,
+ Bool sync,
+ CARD16 width, CARD16 height
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ if (pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ xf86XVCopyCompositeClip(portPriv, pGC, pDraw);
+
+ WinBox.x1 = pDraw->x + drw_x;
+ WinBox.y1 = pDraw->y + drw_y;
+ WinBox.x2 = WinBox.x1 + drw_w;
+ WinBox.y2 = WinBox.y1 + drw_h;
+
+ RegionInit(&WinRegion, &WinBox, 1);
+ RegionNull(&ClipRegion);
+ RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
+
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = portPriv->pScrn->frameX0;
+ VPBox.y1 = portPriv->pScrn->frameY0;
+ VPBox.x2 = portPriv->pScrn->frameX1 + 1;
+ VPBox.y2 = portPriv->pScrn->frameY1 + 1;
+
+ RegionInit(&VPReg, &VPBox, 1);
+ RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
+ RegionUninit(&VPReg);
+ }
+
+ /* If we are changing windows, unregister our port in the old window */
+ if(portPriv->pDraw && (portPriv->pDraw != pDraw))
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+
+ /* Register our port with the new window */
+ ret = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ if(ret != Success) goto PUT_IMAGE_BAILOUT;
+
+ if(!RegionNotEmpty(&ClipRegion)) {
+ clippedAway = TRUE;
+ goto PUT_IMAGE_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = RegionRects(&ClipRegion);
+ if( (RegionNumRects(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto PUT_IMAGE_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->PutImage)(portPriv->pScrn,
+ src_x, src_y, WinBox.x1, WinBox.y1,
+ src_w, src_h, drw_w, drw_h, format->id, data, width, height,
+ sync, &ClipRegion, portPriv->DevPriv.ptr,
+ pDraw);
+
+ if((ret == Success) &&
+ (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) {
+
+ portPriv->isOn = XV_ON;
+ portPriv->vid_x = src_x; portPriv->vid_y = src_y;
+ portPriv->vid_w = src_w; portPriv->vid_h = src_h;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+ portPriv->type = 0; /* no mask means it's transient and should
+ not be reput once it's removed */
+ pPort->pDraw = pDraw; /* make sure we can get stop requests */
+ }
+
+PUT_IMAGE_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ /* This clip was copied and only good for one shot */
+ if(!portPriv->FreeCompositeClip)
+ portPriv->pCompositeClip = NULL;
+
+ RegionUninit(&WinRegion);
+ RegionUninit(&ClipRegion);
+
+ return ret;
+}
+
+
+static int
+xf86XVQueryImageAttributes(
+ ClientPtr client,
+ XvPortPtr pPort,
+ XvImagePtr format,
+ CARD16 *width,
+ CARD16 *height,
+ int *pitches,
+ int *offsets
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ return (*portPriv->AdaptorRec->QueryImageAttributes)(portPriv->pScrn,
+ format->id, width, height, pitches, offsets);
+}
+
+void
+xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr fillboxes)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ ChangeGCVal pval[2];
+ BoxPtr pbox = RegionRects(fillboxes);
+ int i, nbox = RegionNumRects(fillboxes);
+ xRectangle *rects;
+ GCPtr gc;
+
+ if(!xf86Screens[pScreen->myNum]->vtSema) return;
+
+ gc = GetScratchGC(pDraw->depth, pScreen);
+ pval[0].val = key;
+ pval[1].val = IncludeInferiors;
+ (void) ChangeGC(NullClient, gc, GCForeground|GCSubwindowMode, pval);
+ ValidateGC(pDraw, gc);
+
+ rects = malloc(nbox * sizeof(xRectangle));
+
+ for(i = 0; i < nbox; i++, pbox++)
+ {
+ rects[i].x = pbox->x1 - pDraw->x;
+ rects[i].y = pbox->y1 - pDraw->y;
+ rects[i].width = pbox->x2 - pbox->x1;
+ rects[i].height = pbox->y2 - pbox->y1;
+ }
+
+ (*gc->ops->PolyFillRect)(pDraw, gc, nbox, rects);
+
+ free(rects);
+ FreeScratchGC (gc);
+}
+
+void
+xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr fillboxes)
+{
+ xf86XVFillKeyHelperDrawable (&pScreen->root->drawable, key, fillboxes);
+}
+
+void
+xf86XVFillKeyHelperPort (DrawablePtr pDraw, pointer data, CARD32 key, RegionPtr clipboxes, Bool fillEverything)
+{
+ WindowPtr pWin = (WindowPtr)pDraw;
+ XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
+ XvPortRecPrivatePtr portPriv = NULL;
+ RegionRec reg;
+ RegionPtr fillboxes;
+
+ while (WinPriv) {
+ XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
+
+ if (data == pPriv->DevPriv.ptr) {
+ portPriv = pPriv;
+ break;
+ }
+
+ WinPriv = WinPriv->next;
+ }
+
+ if (!portPriv)
+ return;
+
+ if (!portPriv->ckeyFilled)
+ portPriv->ckeyFilled = RegionCreate(NULL, 0);
+
+ if (!fillEverything) {
+ RegionNull(&reg);
+ fillboxes = &reg;
+ RegionSubtract(fillboxes, clipboxes, portPriv->ckeyFilled);
+
+ if (!RegionNotEmpty(fillboxes))
+ goto out;
+ } else
+ fillboxes = clipboxes;
+
+
+ RegionCopy(portPriv->ckeyFilled, clipboxes);
+
+ xf86XVFillKeyHelperDrawable(pDraw, key, fillboxes);
+out:
+ if (!fillEverything)
+ RegionUninit(&reg);
+}
+
+
+/* xf86XVClipVideoHelper -
+
+ Takes the dst box in standard X BoxRec form (top and left
+ edges inclusive, bottom and right exclusive). The new dst
+ box is returned. The source boundaries are given (x1, y1
+ inclusive, x2, y2 exclusive) and returned are the new source
+ boundaries in 16.16 fixed point.
+*/
+
+Bool
+xf86XVClipVideoHelper(
+ BoxPtr dst,
+ INT32 *xa,
+ INT32 *xb,
+ INT32 *ya,
+ INT32 *yb,
+ RegionPtr reg,
+ INT32 width,
+ INT32 height
+){
+ double xsw, xdw, ysw, ydw;
+ INT32 delta;
+ BoxPtr extents = RegionExtents(reg);
+ int diff;
+
+ xsw = (*xb - *xa) << 16;
+ xdw = dst->x2 - dst->x1;
+ ysw = (*yb - *ya) << 16;
+ ydw = dst->y2 - dst->y1;
+
+ *xa <<= 16; *xb <<= 16;
+ *ya <<= 16; *yb <<= 16;
+
+ diff = extents->x1 - dst->x1;
+ if (diff > 0) {
+ dst->x1 = extents->x1;
+ *xa += (diff * xsw) / xdw;
+ }
+ diff = dst->x2 - extents->x2;
+ if (diff > 0) {
+ dst->x2 = extents->x2;
+ *xb -= (diff * xsw) / xdw;
+ }
+ diff = extents->y1 - dst->y1;
+ if (diff > 0) {
+ dst->y1 = extents->y1;
+ *ya += (diff * ysw) / ydw;
+ }
+ diff = dst->y2 - extents->y2;
+ if (diff > 0) {
+ dst->y2 = extents->y2;
+ *yb -= (diff * ysw) / ydw;
+ }
+
+ if (*xa < 0) {
+ diff = (((-*xa) * xdw) + xsw - 1) / xsw;
+ dst->x1 += diff;
+ *xa += (diff * xsw) / xdw;
+ }
+ delta = *xb - (width << 16);
+ if (delta > 0) {
+ diff = ((delta * xdw) + xsw - 1) / xsw;
+ dst->x2 -= diff;
+ *xb -= (diff * xsw) / xdw;
+ }
+ if (*xa >= *xb) return FALSE;
+
+ if (*ya < 0) {
+ diff = (((-*ya) * ydw) + ysw - 1) / ysw;
+ dst->y1 += diff;
+ *ya += (diff * ysw) / ydw;
+ }
+ delta = *yb - (height << 16);
+ if (delta > 0) {
+ diff = ((delta * ydw) + ysw - 1) / ysw;
+ dst->y2 -= diff;
+ *yb -= (diff * ysw) / ydw;
+ }
+ if (*ya >= *yb) return FALSE;
+
+ if ((dst->x1 > extents->x1) || (dst->x2 < extents->x2) ||
+ (dst->y1 > extents->y1) || (dst->y2 < extents->y2))
+ {
+ RegionRec clipReg;
+ RegionInit(&clipReg, dst, 1);
+ RegionIntersect(reg, reg, &clipReg);
+ RegionUninit(&clipReg);
+ }
+ return TRUE;
+}
+
+void
+xf86XVCopyYUV12ToPacked(
+ const void *srcy,
+ const void *srcv,
+ const void *srcu,
+ void *dst,
+ int srcPitchy,
+ int srcPitchuv,
+ int dstPitch,
+ int h,
+ int w
+){
+ CARD32 *Dst;
+ const CARD8 *Y, *U, *V;
+ int i, j;
+
+ w >>= 1;
+
+ for (j = 0; j < h; j++) {
+ Dst = dst;
+ Y = srcy; V = srcv; U = srcu;
+ i = w;
+ while (i >= 4) {
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+ Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24);
+ Dst[1] = Y[2] | (Y[3] << 16) | (U[1] << 8) | (V[1] << 24);
+ Dst[2] = Y[4] | (Y[5] << 16) | (U[2] << 8) | (V[2] << 24);
+ Dst[3] = Y[6] | (Y[7] << 16) | (U[3] << 8) | (V[3] << 24);
+#else
+ /* This assumes a little-endian framebuffer */
+ Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0];
+ Dst[1] = (Y[2] << 24) | (Y[3] << 8) | (U[1] << 16) | V[1];
+ Dst[2] = (Y[4] << 24) | (Y[5] << 8) | (U[2] << 16) | V[2];
+ Dst[3] = (Y[6] << 24) | (Y[7] << 8) | (U[3] << 16) | V[3];
+#endif
+ Dst += 4; Y += 8; V += 4; U += 4;
+ i -= 4;
+ }
+
+ while (i--) {
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+ Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24);
+#else
+ /* This assumes a little-endian framebuffer */
+ Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0];
+#endif
+ Dst++; Y += 2; V++; U++;
+ }
+
+ dst = (CARD8 *)dst + dstPitch;
+ srcy = (const CARD8 *)srcy + srcPitchy;
+ if (j & 1) {
+ srcu = (const CARD8 *)srcu + srcPitchuv;
+ srcv = (const CARD8 *)srcv + srcPitchuv;
+ }
+ }
+}
+
+void
+xf86XVCopyPacked(
+ const void *src,
+ void *dst,
+ int srcPitch,
+ int dstPitch,
+ int h,
+ int w
+){
+ const CARD32 *Src;
+ CARD32 *Dst;
+ int i;
+
+ w >>= 1;
+ while (--h >= 0) {
+ do {
+ Dst = dst; Src = src;
+ i = w;
+ while (i >= 4) {
+ Dst[0] = Src[0];
+ Dst[1] = Src[1];
+ Dst[2] = Src[2];
+ Dst[3] = Src[3];
+ Dst += 4; Src += 4; i -= 4;
+ }
+ if (!i) break;
+ Dst[0] = Src[0];
+ if (i == 1) break;
+ Dst[1] = Src[1];
+ if (i == 2) break;
+ Dst[2] = Src[2];
+ } while (0);
+
+ src = (const CARD8 *)src + srcPitch;
+ dst = (CARD8 *)dst + dstPitch;
+ }
+}
diff --git a/xorg-server/hw/xfree86/ddc/ddcProperty.c b/xorg-server/hw/xfree86/ddc/ddcProperty.c
index 5d6eec927..36ade8a5f 100644
--- a/xorg-server/hw/xfree86/ddc/ddcProperty.c
+++ b/xorg-server/hw/xfree86/ddc/ddcProperty.c
@@ -1,124 +1,124 @@
-/*
- * Copyright 2006 Luc Verhaegen.
- *
- * 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, sub license,
- * 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 NON-INFRINGEMENT. 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_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include <X11/Xatom.h>
-#include "property.h"
-#include "propertyst.h"
-#include <string.h>
-
-#define EDID1_ATOM_NAME "XFree86_DDC_EDID1_RAWDATA"
-#define EDID2_ATOM_NAME "XFree86_DDC_EDID2_RAWDATA"
-
-static void
-edidMakeAtom(int i, const char *name, CARD8 *data, int size)
-{
- Atom atom;
- unsigned char *atom_data;
-
- if (!(atom_data = malloc(size*sizeof(CARD8))))
- return;
-
- atom = MakeAtom(name, strlen(name), TRUE);
- memcpy(atom_data, data, size);
- xf86RegisterRootWindowProperty(i, atom, XA_INTEGER, 8, size, atom_data);
-}
-
-static void
-addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
-{
- int i, scrnIndex = pScrn->scrnIndex;
- Bool makeEDID1prop = FALSE;
- Bool makeEDID2prop = FALSE;
-
- if (DDC->flags & MONITOR_DISPLAYID) {
- /* Don't bother, use RANDR already */
- return;
- } else if (DDC->ver.version == 1) {
- makeEDID1prop = TRUE;
- } else if (DDC->ver.version == 2) {
- int checksum1;
- int checksum2;
- makeEDID2prop = TRUE;
-
- /* Some monitors (eg Panasonic PanaSync4)
- * report version==2 because they used EDID v2 spec document,
- * although they use EDID v1 data structure :-(
- *
- * Try using checksum to determine when we have such a monitor.
- */
- checksum2 = 0;
- for (i = 0; i < 256; i++)
- checksum2 += DDC->rawData[i];
- if (checksum2 % 256) {
- xf86DrvMsg(scrnIndex, X_INFO, "Monitor EDID v2 checksum failed\n");
- xf86DrvMsg(scrnIndex, X_INFO,
- "XFree86_DDC_EDID2_RAWDATA property may be bad\n");
- checksum1 = 0;
- for (i = 0; i < 128; i++)
- checksum1 += DDC->rawData[i];
- if (!(checksum1 % 256)) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "Monitor EDID v1 checksum passed,\n");
- xf86DrvMsg(scrnIndex, X_INFO,
- "XFree86_DDC_EDID1_RAWDATA property created\n");
- makeEDID1prop = TRUE;
- }
- }
- } else {
- xf86DrvMsg(scrnIndex, X_PROBED, "unexpected EDID version %d.%d\n",
- DDC->ver.version, DDC->ver.revision);
- return;
- }
-
- if (makeEDID1prop) {
- int size = 128 +
- (DDC->flags & EDID_COMPLETE_RAWDATA ? DDC->no_sections * 128 : 0);
-
- edidMakeAtom(scrnIndex, EDID1_ATOM_NAME, DDC->rawData, size);
- }
-
- if (makeEDID2prop)
- edidMakeAtom(scrnIndex, EDID2_ATOM_NAME, DDC->rawData, 256);
-}
-
-Bool
-xf86SetDDCproperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
-{
- if (!pScrn || !pScrn->monitor || !DDC)
- return FALSE;
-
- if (DDC->flags & MONITOR_DISPLAYID)
- ;
- else
- xf86EdidMonitorSet(pScrn->scrnIndex, pScrn->monitor, DDC);
-
- addRootWindowProperties(pScrn, DDC);
-
- return TRUE;
-}
+/*
+ * Copyright 2006 Luc Verhaegen.
+ *
+ * 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, sub license,
+ * 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 NON-INFRINGEMENT. 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_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86DDC.h"
+#include <X11/Xatom.h>
+#include "property.h"
+#include "propertyst.h"
+#include <string.h>
+
+#define EDID1_ATOM_NAME "XFree86_DDC_EDID1_RAWDATA"
+#define EDID2_ATOM_NAME "XFree86_DDC_EDID2_RAWDATA"
+
+static void
+edidMakeAtom(int i, const char *name, CARD8 *data, int size)
+{
+ Atom atom;
+ unsigned char *atom_data;
+
+ if (!(atom_data = malloc(size*sizeof(CARD8))))
+ return;
+
+ atom = MakeAtom(name, strlen(name), TRUE);
+ memcpy(atom_data, data, size);
+ xf86RegisterRootWindowProperty(i, atom, XA_INTEGER, 8, size, atom_data);
+}
+
+static void
+addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
+{
+ int i, scrnIndex = pScrn->scrnIndex;
+ Bool makeEDID1prop = FALSE;
+ Bool makeEDID2prop = FALSE;
+
+ if (DDC->flags & MONITOR_DISPLAYID) {
+ /* Don't bother, use RANDR already */
+ return;
+ } else if (DDC->ver.version == 1) {
+ makeEDID1prop = TRUE;
+ } else if (DDC->ver.version == 2) {
+ int checksum1;
+ int checksum2;
+ makeEDID2prop = TRUE;
+
+ /* Some monitors (eg Panasonic PanaSync4)
+ * report version==2 because they used EDID v2 spec document,
+ * although they use EDID v1 data structure :-(
+ *
+ * Try using checksum to determine when we have such a monitor.
+ */
+ checksum2 = 0;
+ for (i = 0; i < 256; i++)
+ checksum2 += DDC->rawData[i];
+ if (checksum2 % 256) {
+ xf86DrvMsg(scrnIndex, X_INFO, "Monitor EDID v2 checksum failed\n");
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "XFree86_DDC_EDID2_RAWDATA property may be bad\n");
+ checksum1 = 0;
+ for (i = 0; i < 128; i++)
+ checksum1 += DDC->rawData[i];
+ if (!(checksum1 % 256)) {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Monitor EDID v1 checksum passed,\n");
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "XFree86_DDC_EDID1_RAWDATA property created\n");
+ makeEDID1prop = TRUE;
+ }
+ }
+ } else {
+ xf86DrvMsg(scrnIndex, X_PROBED, "unexpected EDID version %d.%d\n",
+ DDC->ver.version, DDC->ver.revision);
+ return;
+ }
+
+ if (makeEDID1prop) {
+ int size = 128 +
+ (DDC->flags & EDID_COMPLETE_RAWDATA ? DDC->no_sections * 128 : 0);
+
+ edidMakeAtom(scrnIndex, EDID1_ATOM_NAME, DDC->rawData, size);
+ }
+
+ if (makeEDID2prop)
+ edidMakeAtom(scrnIndex, EDID2_ATOM_NAME, DDC->rawData, 256);
+}
+
+Bool
+xf86SetDDCproperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
+{
+ if (!pScrn || !pScrn->monitor || !DDC)
+ return FALSE;
+
+ if (DDC->flags & MONITOR_DISPLAYID)
+ ;
+ else
+ xf86EdidMonitorSet(pScrn->scrnIndex, pScrn->monitor, DDC);
+
+ addRootWindowProperties(pScrn, DDC);
+
+ return TRUE;
+}
diff --git a/xorg-server/hw/xfree86/dri/dri.c b/xorg-server/hw/xfree86/dri/dri.c
index 1726960ae..cf83c002e 100644
--- a/xorg-server/hw/xfree86/dri/dri.c
+++ b/xorg-server/hw/xfree86/dri/dri.c
@@ -1,2496 +1,2496 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, Inc.
-All Rights Reserved.
-
-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, sub license, 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 NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Jens Owen <jens@tungstengraphics.com>
- * Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include <sys/time.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "xf86drm.h"
-#include "misc.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "servermd.h"
-#define _XF86DRI_SERVER_
-#include <X11/dri/xf86driproto.h>
-#include "swaprep.h"
-#include "xf86str.h"
-#include "dri.h"
-#include "sarea.h"
-#include "dristruct.h"
-#include "mi.h"
-#include "mipointer.h"
-#include "xf86_OSproc.h"
-#include "inputstr.h"
-#include "xf86VGAarbiter.h"
-
-static int DRIEntPrivIndex = -1;
-static DevPrivateKeyRec DRIScreenPrivKeyRec;
-#define DRIScreenPrivKey (&DRIScreenPrivKeyRec)
-static DevPrivateKeyRec DRIWindowPrivKeyRec;
-#define DRIWindowPrivKey (&DRIWindowPrivKeyRec)
-static unsigned long DRIGeneration = 0;
-static unsigned int DRIDrawableValidationStamp = 0;
-
-static RESTYPE DRIDrawablePrivResType;
-static RESTYPE DRIContextPrivResType;
-static void DRIDestroyDummyContext(ScreenPtr pScreen, Bool hasCtxPriv);
-
-drmServerInfo DRIDRMServerInfo;
-
- /* Wrapper just like xf86DrvMsg, but
- without the verbosity level checking.
- This will make it easy to turn off some
- messages later, based on verbosity
- level. */
-
-/*
- * Since we're already referencing things from the XFree86 common layer in
- * this file, we'd might as well just call xf86VDrvMsgVerb, and have
- * consistent message formatting. The verbosity of these messages can be
- * easily changed here.
- */
-#define DRI_MSG_VERBOSITY 1
-static void
-DRIDrvMsg(int scrnIndex, MessageType type, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- xf86VDrvMsgVerb(scrnIndex, type, DRI_MSG_VERBOSITY, format, ap);
- va_end(ap);
-}
-
-
-static void
-DRIOpenDRMCleanup(DRIEntPrivPtr pDRIEntPriv)
-{
- if (pDRIEntPriv->pLSAREA != NULL) {
- drmUnmap(pDRIEntPriv->pLSAREA, pDRIEntPriv->sAreaSize);
- pDRIEntPriv->pLSAREA = NULL;
- }
- if (pDRIEntPriv->hLSAREA != 0) {
- drmRmMap(pDRIEntPriv->drmFD, pDRIEntPriv->hLSAREA);
- }
- if (pDRIEntPriv->drmFD >= 0) {
- drmClose(pDRIEntPriv->drmFD);
- pDRIEntPriv->drmFD = 0;
- }
-}
-
-int
-DRIMasterFD(ScrnInfoPtr pScrn)
-{
- return DRI_ENT_PRIV(pScrn)->drmFD;
-}
-
-void *
-DRIMasterSareaPointer(ScrnInfoPtr pScrn)
-{
- return DRI_ENT_PRIV(pScrn)->pLSAREA;
-}
-
-drm_handle_t
-DRIMasterSareaHandle(ScrnInfoPtr pScrn)
-{
- return DRI_ENT_PRIV(pScrn)->hLSAREA;
-}
-
-
-Bool
-DRIOpenDRMMaster(ScrnInfoPtr pScrn,
- unsigned long sAreaSize,
- const char *busID,
- const char *drmDriverName)
-{
- drmSetVersion saveSv, sv;
- Bool drmWasAvailable;
- DRIEntPrivPtr pDRIEntPriv;
- DRIEntPrivRec tmp;
- drmVersionPtr drmlibv;
- int drmlibmajor, drmlibminor;
- const char *openBusID;
- int count;
- int err;
-
- if (DRIEntPrivIndex == -1)
- DRIEntPrivIndex = xf86AllocateEntityPrivateIndex();
-
- pDRIEntPriv = DRI_ENT_PRIV(pScrn);
-
- if (pDRIEntPriv && pDRIEntPriv->drmFD != -1)
- return TRUE;
-
- drmWasAvailable = drmAvailable();
-
- memset(&tmp, 0, sizeof(tmp));
-
- /* Check the DRM lib version.
- * drmGetLibVersion was not supported in version 1.0, so check for
- * symbol first to avoid possible crash or hang.
- */
-
- drmlibmajor = 1;
- drmlibminor = 0;
- if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
- drmlibv = drmGetLibVersion(-1);
- if (drmlibv != NULL) {
- drmlibmajor = drmlibv->version_major;
- drmlibminor = drmlibv->version_minor;
- drmFreeVersion(drmlibv);
- }
- }
-
- /* Check if the libdrm can handle falling back to loading based on name
- * if a busid string is passed.
- */
- openBusID = (drmlibmajor == 1 && drmlibminor >= 2) ? busID : NULL;
-
- tmp.drmFD = -1;
- sv.drm_di_major = 1;
- sv.drm_di_minor = 1;
- sv.drm_dd_major = -1;
-
- saveSv = sv;
- count = 10;
- while (count--) {
- tmp.drmFD = drmOpen(drmDriverName, openBusID);
-
- if (tmp.drmFD < 0) {
- DRIDrvMsg(-1, X_ERROR, "[drm] drmOpen failed.\n");
- goto out_err;
- }
-
- err = drmSetInterfaceVersion(tmp.drmFD, &sv);
-
- if (err != -EPERM)
- break;
-
- sv = saveSv;
- drmClose(tmp.drmFD);
- tmp.drmFD = -1;
- usleep(100000);
- }
-
- if (tmp.drmFD <= 0) {
- DRIDrvMsg(-1, X_ERROR, "[drm] DRM was busy with another master.\n");
- goto out_err;
- }
-
- if (!drmWasAvailable) {
- DRIDrvMsg(-1, X_INFO,
- "[drm] loaded kernel module for \"%s\" driver.\n",
- drmDriverName);
- }
-
- if (err != 0) {
- sv.drm_di_major = 1;
- sv.drm_di_minor = 0;
- }
-
- DRIDrvMsg(-1, X_INFO, "[drm] DRM interface version %d.%d\n",
- sv.drm_di_major, sv.drm_di_minor);
-
- if (sv.drm_di_major == 1 && sv.drm_di_minor >= 1)
- err = 0;
- else
- err = drmSetBusid(tmp.drmFD, busID);
-
- if (err) {
- DRIDrvMsg(-1, X_ERROR, "[drm] Could not set DRM device bus ID.\n");
- goto out_err;
- }
-
- /*
- * Create a lock-containing sarea.
- */
-
- if (drmAddMap( tmp.drmFD, 0, sAreaSize, DRM_SHM,
- DRM_CONTAINS_LOCK, &tmp.hLSAREA) < 0) {
- DRIDrvMsg(-1, X_INFO, "[drm] Could not create SAREA for DRM lock.\n");
- tmp.hLSAREA = 0;
- goto out_err;
- }
-
- if (drmMap( tmp.drmFD, tmp.hLSAREA, sAreaSize,
- (drmAddressPtr)(&tmp.pLSAREA)) < 0) {
- DRIDrvMsg(-1, X_INFO, "[drm] Mapping SAREA for DRM lock failed.\n");
- tmp.pLSAREA = NULL;
- goto out_err;
- }
-
- memset(tmp.pLSAREA, 0, sAreaSize);
-
- /*
- * Reserved contexts are handled by the first opened screen.
- */
-
- tmp.resOwner = NULL;
-
- if (!pDRIEntPriv)
- pDRIEntPriv = xnfcalloc(sizeof(*pDRIEntPriv), 1);
-
- if (!pDRIEntPriv) {
- DRIDrvMsg(-1, X_INFO, "[drm] Failed to allocate memory for "
- "DRM device.\n");
- goto out_err;
- }
- *pDRIEntPriv = tmp;
- xf86GetEntityPrivate((pScrn)->entityList[0],DRIEntPrivIndex)->ptr =
- pDRIEntPriv;
-
- DRIDrvMsg(-1, X_INFO, "[drm] DRM open master succeeded.\n");
- return TRUE;
-
- out_err:
-
- DRIOpenDRMCleanup(&tmp);
- return FALSE;
-}
-
-static void
-DRIClipNotifyAllDrawables(ScreenPtr pScreen);
-
-static void
-dri_crtc_notify(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIClipNotifyAllDrawables(pScreen);
- xf86_unwrap_crtc_notify(pScreen, pDRIPriv->xf86_crtc_notify);
- xf86_crtc_notify(pScreen);
- pDRIPriv->xf86_crtc_notify = xf86_wrap_crtc_notify(pScreen, dri_crtc_notify);
-}
-
-Bool
-DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
-{
- DRIScreenPrivPtr pDRIPriv;
- drm_context_t * reserved;
- int reserved_count;
- int i;
- DRIEntPrivPtr pDRIEntPriv;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- DRIContextFlags flags = 0;
- DRIContextPrivPtr pDRIContextPriv;
-
- /* If the DRI extension is disabled, do not initialize the DRI */
- if (noXFree86DRIExtension) {
- DRIDrvMsg(pScreen->myNum, X_WARNING,
- "Direct rendering has been disabled.\n");
- return FALSE;
- }
-
- if (!xf86VGAarbiterAllowDRI(pScreen)) {
- DRIDrvMsg(pScreen->myNum, X_WARNING,
- "Direct rendering is not supported when VGA arb is necessary for the device\n");
- return FALSE;
- }
-
-#ifdef PANORAMIX
- /*
- * If Xinerama is on, don't allow DRI to initialise. It won't be usable
- * anyway.
- */
- if (!noPanoramiXExtension) {
- DRIDrvMsg(pScreen->myNum, X_WARNING,
- "Direct rendering is not supported when Xinerama is enabled\n");
- return FALSE;
- }
-#endif
-
- if (!DRIOpenDRMMaster(pScrn, pDRIInfo->SAREASize,
- pDRIInfo->busIdString,
- pDRIInfo->drmDriverName))
- return FALSE;
-
- pDRIEntPriv = DRI_ENT_PRIV(pScrn);
-
- if (DRIGeneration != serverGeneration)
- DRIGeneration = serverGeneration;
-
- if (!dixRegisterPrivateKey(&DRIScreenPrivKeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
- if (!dixRegisterPrivateKey(&DRIWindowPrivKeyRec, PRIVATE_WINDOW, 0))
- return FALSE;
-
- pDRIPriv = (DRIScreenPrivPtr) calloc(1, sizeof(DRIScreenPrivRec));
- if (!pDRIPriv) {
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
- return FALSE;
- }
-
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, pDRIPriv);
- pDRIPriv->drmFD = pDRIEntPriv->drmFD;
- pDRIPriv->directRenderingSupport = TRUE;
- pDRIPriv->pDriverInfo = pDRIInfo;
- pDRIPriv->nrWindows = 0;
- pDRIPriv->nrWindowsVisible = 0;
- pDRIPriv->fullscreen = NULL;
-
- pDRIPriv->createDummyCtx = pDRIInfo->createDummyCtx;
- pDRIPriv->createDummyCtxPriv = pDRIInfo->createDummyCtxPriv;
-
- pDRIPriv->grabbedDRILock = FALSE;
- pDRIPriv->drmSIGIOHandlerInstalled = FALSE;
- *pDRMFD = pDRIPriv->drmFD;
-
- if (pDRIEntPriv->sAreaGrabbed || pDRIInfo->allocSarea) {
-
- if (drmAddMap( pDRIPriv->drmFD,
- 0,
- pDRIPriv->pDriverInfo->SAREASize,
- DRM_SHM,
- 0,
- &pDRIPriv->hSAREA) < 0)
- {
- pDRIPriv->directRenderingSupport = FALSE;
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
- drmClose(pDRIPriv->drmFD);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] drmAddMap failed\n");
- return FALSE;
- }
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] added %d byte SAREA at %p\n",
- pDRIPriv->pDriverInfo->SAREASize, pDRIPriv->hSAREA);
-
- /* Backwards compat. */
- if (drmMap( pDRIPriv->drmFD,
- pDRIPriv->hSAREA,
- pDRIPriv->pDriverInfo->SAREASize,
- (drmAddressPtr)(&pDRIPriv->pSAREA)) < 0)
- {
- pDRIPriv->directRenderingSupport = FALSE;
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
- drmClose(pDRIPriv->drmFD);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] drmMap failed\n");
- return FALSE;
- }
- DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] mapped SAREA %p to %p\n",
- pDRIPriv->hSAREA, pDRIPriv->pSAREA);
- memset(pDRIPriv->pSAREA, 0, pDRIPriv->pDriverInfo->SAREASize);
- } else {
- DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] Using the DRM lock "
- "SAREA also for drawables.\n");
- pDRIPriv->hSAREA = pDRIEntPriv->hLSAREA;
- pDRIPriv->pSAREA = (XF86DRISAREAPtr) pDRIEntPriv->pLSAREA;
- pDRIEntPriv->sAreaGrabbed = TRUE;
- }
-
- pDRIPriv->hLSAREA = pDRIEntPriv->hLSAREA;
- pDRIPriv->pLSAREA = pDRIEntPriv->pLSAREA;
-
- if (!pDRIPriv->pDriverInfo->dontMapFrameBuffer)
- {
- if (drmAddMap( pDRIPriv->drmFD,
- (uintptr_t)pDRIPriv->pDriverInfo->frameBufferPhysicalAddress,
- pDRIPriv->pDriverInfo->frameBufferSize,
- DRM_FRAME_BUFFER,
- 0,
- &pDRIPriv->pDriverInfo->hFrameBuffer) < 0)
- {
- pDRIPriv->directRenderingSupport = FALSE;
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
- drmUnmap(pDRIPriv->pSAREA, pDRIPriv->pDriverInfo->SAREASize);
- drmClose(pDRIPriv->drmFD);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] drmAddMap failed\n");
- return FALSE;
- }
- DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] framebuffer handle = %p\n",
- pDRIPriv->pDriverInfo->hFrameBuffer);
- } else {
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] framebuffer mapped by ddx driver\n");
- }
-
- if (pDRIEntPriv->resOwner == NULL) {
- pDRIEntPriv->resOwner = pScreen;
-
- /* Add tags for reserved contexts */
- if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
- &reserved_count))) {
- int i;
- void *tag;
-
- for (i = 0; i < reserved_count; i++) {
- tag = DRICreateContextPrivFromHandle(pScreen,
- reserved[i],
- DRI_CONTEXT_RESERVED);
- drmAddContextTag(pDRIPriv->drmFD, reserved[i], tag);
- }
- drmFreeReservedContextList(reserved);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] added %d reserved context%s for kernel\n",
- reserved_count, reserved_count > 1 ? "s" : "");
- }
- }
-
- /* validate max drawable table entry set by driver */
- if ((pDRIPriv->pDriverInfo->maxDrawableTableEntry <= 0) ||
- (pDRIPriv->pDriverInfo->maxDrawableTableEntry > SAREA_MAX_DRAWABLES)) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "Invalid max drawable table size set by driver: %d\n",
- pDRIPriv->pDriverInfo->maxDrawableTableEntry);
- }
-
- /* Initialize drawable tables (screen private and SAREA) */
- for( i=0; i < pDRIPriv->pDriverInfo->maxDrawableTableEntry; i++) {
- pDRIPriv->DRIDrawables[i] = NULL;
- pDRIPriv->pSAREA->drawableTable[i].stamp = 0;
- pDRIPriv->pSAREA->drawableTable[i].flags = 0;
- }
-
- pDRIPriv->pLockRefCount = &pDRIEntPriv->lockRefCount;
- pDRIPriv->pLockingContext = &pDRIEntPriv->lockingContext;
-
- if (!pDRIEntPriv->keepFDOpen)
- pDRIEntPriv->keepFDOpen = pDRIInfo->keepFDOpen;
-
- pDRIEntPriv->refCount++;
-
- /* Set up flags for DRICreateContextPriv */
- switch (pDRIInfo->driverSwapMethod) {
- case DRI_KERNEL_SWAP:
- flags = DRI_CONTEXT_2DONLY;
- break;
- case DRI_HIDE_X_CONTEXT:
- flags = DRI_CONTEXT_PRESERVED;
- break;
- }
-
- if (!(pDRIContextPriv = DRICreateContextPriv(pScreen,
- &pDRIPriv->myContext,
- flags))) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "failed to create server context\n");
- return FALSE;
- }
- pDRIPriv->myContextPriv = pDRIContextPriv;
-
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "X context handle = %p\n", pDRIPriv->myContext);
-
- /* Now that we have created the X server's context, we can grab the
- * hardware lock for the X server.
- */
- DRILock(pScreen, 0);
- pDRIPriv->grabbedDRILock = TRUE;
-
- /* pointers so that we can prevent memory leaks later */
- pDRIPriv->hiddenContextStore = NULL;
- pDRIPriv->partial3DContextStore = NULL;
-
- switch(pDRIInfo->driverSwapMethod) {
- case DRI_HIDE_X_CONTEXT:
- /* Server will handle 3D swaps, and hide 2D swaps from kernel.
- * Register server context as a preserved context.
- */
-
- /* allocate memory for hidden context store */
- pDRIPriv->hiddenContextStore
- = (void *)calloc(1, pDRIInfo->contextSize);
- if (!pDRIPriv->hiddenContextStore) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "failed to allocate hidden context\n");
- DRIDestroyContextPriv(pDRIContextPriv);
- return FALSE;
- }
-
- /* allocate memory for partial 3D context store */
- pDRIPriv->partial3DContextStore
- = (void *)calloc(1, pDRIInfo->contextSize);
- if (!pDRIPriv->partial3DContextStore) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[DRI] failed to allocate partial 3D context\n");
- free(pDRIPriv->hiddenContextStore);
- DRIDestroyContextPriv(pDRIContextPriv);
- return FALSE;
- }
-
- /* save initial context store */
- if (pDRIInfo->SwapContext) {
- (*pDRIInfo->SwapContext)(
- pScreen,
- DRI_NO_SYNC,
- DRI_2D_CONTEXT,
- pDRIPriv->hiddenContextStore,
- DRI_NO_CONTEXT,
- NULL);
- }
- /* fall through */
-
- case DRI_SERVER_SWAP:
- /* For swap methods of DRI_SERVER_SWAP and DRI_HIDE_X_CONTEXT
- * setup signal handler for receiving swap requests from kernel
- */
- if (!(pDRIPriv->drmSIGIOHandlerInstalled =
- drmInstallSIGIOHandler(pDRIPriv->drmFD, DRISwapContext))) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[drm] failed to setup DRM signal handler\n");
- free(pDRIPriv->hiddenContextStore);
- free(pDRIPriv->partial3DContextStore);
- DRIDestroyContextPriv(pDRIContextPriv);
- return FALSE;
- } else {
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] installed DRM signal handler\n");
- }
-
- default:
- break;
- }
-
- return TRUE;
-}
-
-Bool
-DRIFinishScreenInit(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
-
- /* Wrap DRI support */
- if (pDRIInfo->wrap.ValidateTree) {
- pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
- pScreen->ValidateTree = pDRIInfo->wrap.ValidateTree;
- }
- if (pDRIInfo->wrap.PostValidateTree) {
- pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
- pScreen->PostValidateTree = pDRIInfo->wrap.PostValidateTree;
- }
- if (pDRIInfo->wrap.WindowExposures) {
- pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
- pScreen->WindowExposures = pDRIInfo->wrap.WindowExposures;
- }
-
- pDRIPriv->DestroyWindow = pScreen->DestroyWindow;
- pScreen->DestroyWindow = DRIDestroyWindow;
-
- pDRIPriv->xf86_crtc_notify = xf86_wrap_crtc_notify(pScreen,
- dri_crtc_notify);
-
- if (pDRIInfo->wrap.CopyWindow) {
- pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
- pScreen->CopyWindow = pDRIInfo->wrap.CopyWindow;
- }
- if (pDRIInfo->wrap.ClipNotify) {
- pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
- pScreen->ClipNotify = pDRIInfo->wrap.ClipNotify;
- }
- if (pDRIInfo->wrap.AdjustFrame) {
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- pDRIPriv->wrap.AdjustFrame = pScrn->AdjustFrame;
- pScrn->AdjustFrame = pDRIInfo->wrap.AdjustFrame;
- }
- pDRIPriv->wrapped = TRUE;
-
- DRIDrvMsg(pScreen->myNum, X_INFO, "[DRI] installation complete\n");
-
- return TRUE;
-}
-
-void
-DRICloseScreen(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIInfoPtr pDRIInfo;
- drm_context_t * reserved;
- int reserved_count;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- DRIEntPrivPtr pDRIEntPriv = DRI_ENT_PRIV(pScrn);
- Bool closeMaster;
-
- if (pDRIPriv) {
-
- pDRIInfo = pDRIPriv->pDriverInfo;
-
- if (pDRIPriv->wrapped) {
- /* Unwrap DRI Functions */
- if (pDRIInfo->wrap.ValidateTree) {
- pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree;
- pDRIPriv->wrap.ValidateTree = NULL;
- }
- if (pDRIInfo->wrap.PostValidateTree) {
- pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree;
- pDRIPriv->wrap.PostValidateTree = NULL;
- }
- if (pDRIInfo->wrap.WindowExposures) {
- pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
- pDRIPriv->wrap.WindowExposures = NULL;
- }
- if (pDRIPriv->DestroyWindow) {
- pScreen->DestroyWindow = pDRIPriv->DestroyWindow;
- pDRIPriv->DestroyWindow = NULL;
- }
-
- xf86_unwrap_crtc_notify(pScreen, pDRIPriv->xf86_crtc_notify);
-
- if (pDRIInfo->wrap.CopyWindow) {
- pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
- pDRIPriv->wrap.CopyWindow = NULL;
- }
- if (pDRIInfo->wrap.ClipNotify) {
- pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
- pDRIPriv->wrap.ClipNotify = NULL;
- }
- if (pDRIInfo->wrap.AdjustFrame) {
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- pScrn->AdjustFrame = pDRIPriv->wrap.AdjustFrame;
- pDRIPriv->wrap.AdjustFrame = NULL;
- }
-
- pDRIPriv->wrapped = FALSE;
- }
-
- if (pDRIPriv->drmSIGIOHandlerInstalled) {
- if (!drmRemoveSIGIOHandler(pDRIPriv->drmFD)) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[drm] failed to remove DRM signal handler\n");
- }
- }
-
- if (pDRIPriv->dummyCtxPriv && pDRIPriv->createDummyCtx) {
- DRIDestroyDummyContext(pScreen, pDRIPriv->createDummyCtxPriv);
- }
-
- if (!DRIDestroyContextPriv(pDRIPriv->myContextPriv)) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "failed to destroy server context\n");
- }
-
- /* Remove tags for reserved contexts */
- if (pDRIEntPriv->resOwner == pScreen) {
- pDRIEntPriv->resOwner = NULL;
-
- if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
- &reserved_count))) {
- int i;
-
- for (i = 0; i < reserved_count; i++) {
- DRIDestroyContextPriv(drmGetContextTag(pDRIPriv->drmFD,
- reserved[i]));
- }
- drmFreeReservedContextList(reserved);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] removed %d reserved context%s for kernel\n",
- reserved_count, reserved_count > 1 ? "s" : "");
- }
- }
-
- /* Make sure signals get unblocked etc. */
- drmUnlock(pDRIPriv->drmFD, pDRIPriv->myContext);
- pDRIPriv->pLockRefCount = NULL;
- closeMaster = (--pDRIEntPriv->refCount == 0) &&
- !pDRIEntPriv->keepFDOpen;
- if (closeMaster || pDRIPriv->hSAREA != pDRIEntPriv->hLSAREA) {
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] unmapping %d bytes of SAREA %p at %p\n",
- pDRIInfo->SAREASize,
- pDRIPriv->hSAREA,
- pDRIPriv->pSAREA);
- if (drmUnmap(pDRIPriv->pSAREA, pDRIInfo->SAREASize)) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[drm] unable to unmap %d bytes"
- " of SAREA %p at %p\n",
- pDRIInfo->SAREASize,
- pDRIPriv->hSAREA,
- pDRIPriv->pSAREA);
- }
- } else {
- pDRIEntPriv->sAreaGrabbed = FALSE;
- }
-
- if (closeMaster || (pDRIEntPriv->drmFD != pDRIPriv->drmFD)) {
- drmClose(pDRIPriv->drmFD);
- if (pDRIEntPriv->drmFD == pDRIPriv->drmFD) {
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] Closed DRM master.\n");
- pDRIEntPriv->drmFD = -1;
- }
- }
-
- free(pDRIPriv);
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
- }
-}
-
-#define DRM_MSG_VERBOSITY 3
-
-static int dri_drm_debug_print(const char *format, va_list ap)
-{
- xf86VDrvMsgVerb(-1, X_NONE, DRM_MSG_VERBOSITY, format, ap);
- return 0;
-}
-
-static void dri_drm_get_perms(gid_t *group, mode_t *mode)
-{
- *group = xf86ConfigDRI.group;
- *mode = xf86ConfigDRI.mode;
-}
-
-drmServerInfo DRIDRMServerInfo = {
- dri_drm_debug_print,
- xf86LoadKernelModule,
- dri_drm_get_perms,
-};
-
-Bool
-DRIExtensionInit(void)
-{
- if (DRIGeneration != serverGeneration) {
- return FALSE;
- }
-
- DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete,
- "DRIDrawable");
- DRIContextPrivResType = CreateNewResourceType(DRIContextPrivDelete,
- "DRIContext");
-
- if (!DRIDrawablePrivResType || !DRIContextPrivResType)
- return FALSE;
-
- RegisterBlockAndWakeupHandlers(DRIBlockHandler, DRIWakeupHandler, NULL);
-
- return TRUE;
-}
-
-void
-DRIReset(void)
-{
- /*
- * This stub routine is called when the X Server recycles, resources
- * allocated by DRIExtensionInit need to be managed here.
- *
- * Currently this routine is a stub because all the interesting resources
- * are managed via the screen init process.
- */
-}
-
-Bool
-DRIQueryDirectRenderingCapable(ScreenPtr pScreen, Bool* isCapable)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv)
- *isCapable = pDRIPriv->directRenderingSupport;
- else
- *isCapable = FALSE;
-
- return TRUE;
-}
-
-Bool
-DRIOpenConnection(ScreenPtr pScreen, drm_handle_t * hSAREA, char **busIdString)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- *hSAREA = pDRIPriv->hSAREA;
- *busIdString = pDRIPriv->pDriverInfo->busIdString;
-
- return TRUE;
-}
-
-Bool
-DRIAuthConnection(ScreenPtr pScreen, drm_magic_t magic)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (drmAuthMagic(pDRIPriv->drmFD, magic)) return FALSE;
- return TRUE;
-}
-
-Bool
-DRICloseConnection(ScreenPtr pScreen)
-{
- return TRUE;
-}
-
-Bool
-DRIGetClientDriverName(ScreenPtr pScreen,
- int *ddxDriverMajorVersion,
- int *ddxDriverMinorVersion,
- int *ddxDriverPatchVersion,
- char **clientDriverName)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- *ddxDriverMajorVersion = pDRIPriv->pDriverInfo->ddxDriverMajorVersion;
- *ddxDriverMinorVersion = pDRIPriv->pDriverInfo->ddxDriverMinorVersion;
- *ddxDriverPatchVersion = pDRIPriv->pDriverInfo->ddxDriverPatchVersion;
- *clientDriverName = pDRIPriv->pDriverInfo->clientDriverName;
-
- return TRUE;
-}
-
-/* DRICreateContextPriv and DRICreateContextPrivFromHandle are helper
- functions that layer on drmCreateContext and drmAddContextTag.
-
- DRICreateContextPriv always creates a kernel drm_context_t and then calls
- DRICreateContextPrivFromHandle to create a DRIContextPriv structure for
- DRI tracking. For the SIGIO handler, the drm_context_t is associated with
- DRIContextPrivPtr. Any special flags are stored in the DRIContextPriv
- area and are passed to the kernel (if necessary).
-
- DRICreateContextPriv returns a pointer to newly allocated
- DRIContextPriv, and returns the kernel drm_context_t in pHWContext. */
-
-DRIContextPrivPtr
-DRICreateContextPriv(ScreenPtr pScreen,
- drm_context_t * pHWContext,
- DRIContextFlags flags)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (drmCreateContext(pDRIPriv->drmFD, pHWContext)) {
- return NULL;
- }
-
- return DRICreateContextPrivFromHandle(pScreen, *pHWContext, flags);
-}
-
-DRIContextPrivPtr
-DRICreateContextPrivFromHandle(ScreenPtr pScreen,
- drm_context_t hHWContext,
- DRIContextFlags flags)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIContextPrivPtr pDRIContextPriv;
- int contextPrivSize;
-
- contextPrivSize = sizeof(DRIContextPrivRec) +
- pDRIPriv->pDriverInfo->contextSize;
- if (!(pDRIContextPriv = calloc(1, contextPrivSize))) {
- return NULL;
- }
- pDRIContextPriv->pContextStore = (void *)(pDRIContextPriv + 1);
-
- drmAddContextTag(pDRIPriv->drmFD, hHWContext, pDRIContextPriv);
-
- pDRIContextPriv->hwContext = hHWContext;
- pDRIContextPriv->pScreen = pScreen;
- pDRIContextPriv->flags = flags;
- pDRIContextPriv->valid3D = FALSE;
-
- if (flags & DRI_CONTEXT_2DONLY) {
- if (drmSetContextFlags(pDRIPriv->drmFD,
- hHWContext,
- DRM_CONTEXT_2DONLY)) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[drm] failed to set 2D context flag\n");
- DRIDestroyContextPriv(pDRIContextPriv);
- return NULL;
- }
- }
- if (flags & DRI_CONTEXT_PRESERVED) {
- if (drmSetContextFlags(pDRIPriv->drmFD,
- hHWContext,
- DRM_CONTEXT_PRESERVED)) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[drm] failed to set preserved flag\n");
- DRIDestroyContextPriv(pDRIContextPriv);
- return NULL;
- }
- }
- return pDRIContextPriv;
-}
-
-Bool
-DRIDestroyContextPriv(DRIContextPrivPtr pDRIContextPriv)
-{
- DRIScreenPrivPtr pDRIPriv;
-
- if (!pDRIContextPriv) return TRUE;
-
- pDRIPriv = DRI_SCREEN_PRIV(pDRIContextPriv->pScreen);
-
- if (!(pDRIContextPriv->flags & DRI_CONTEXT_RESERVED)) {
- /* Don't delete reserved contexts from
- kernel area -- the kernel manages its
- reserved contexts itself. */
- if (drmDestroyContext(pDRIPriv->drmFD, pDRIContextPriv->hwContext))
- return FALSE;
- }
-
- /* Remove the tag last to prevent a race
- condition where the context has pending
- buffers. The context can't be re-used
- while in this thread, but buffers can be
- dispatched asynchronously. */
- drmDelContextTag(pDRIPriv->drmFD, pDRIContextPriv->hwContext);
- free(pDRIContextPriv);
- return TRUE;
-}
-
-static Bool
-DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIContextPrivPtr pDRIContextPriv;
- void *contextStore;
-
- if (!(pDRIContextPriv =
- DRICreateContextPriv(pScreen,
- &pDRIPriv->pSAREA->dummy_context, 0))) {
- return FALSE;
- }
-
- contextStore = DRIGetContextStore(pDRIContextPriv);
- if (pDRIPriv->pDriverInfo->CreateContext && needCtxPriv) {
- if (!pDRIPriv->pDriverInfo->CreateContext(pScreen, NULL,
- pDRIPriv->pSAREA->dummy_context,
- NULL,
- (DRIContextType)(long)contextStore)) {
- DRIDestroyContextPriv(pDRIContextPriv);
- return FALSE;
- }
- }
-
- pDRIPriv->dummyCtxPriv = pDRIContextPriv;
- return TRUE;
-}
-
-static void
-DRIDestroyDummyContext(ScreenPtr pScreen, Bool hasCtxPriv)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIContextPrivPtr pDRIContextPriv = pDRIPriv->dummyCtxPriv;
- void *contextStore;
-
- if (!pDRIContextPriv) return;
- if (pDRIPriv->pDriverInfo->DestroyContext && hasCtxPriv) {
- contextStore = DRIGetContextStore(pDRIContextPriv);
- pDRIPriv->pDriverInfo->DestroyContext(pDRIContextPriv->pScreen,
- pDRIContextPriv->hwContext,
- (DRIContextType)(long)contextStore);
- }
-
- DRIDestroyContextPriv(pDRIPriv->dummyCtxPriv);
- pDRIPriv->dummyCtxPriv = NULL;
-}
-
-Bool
-DRICreateContext(ScreenPtr pScreen, VisualPtr visual,
- XID context, drm_context_t * pHWContext)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIContextPrivPtr pDRIContextPriv;
- void *contextStore;
-
- if (pDRIPriv->createDummyCtx && !pDRIPriv->dummyCtxPriv) {
- if (!DRICreateDummyContext(pScreen, pDRIPriv->createDummyCtxPriv)) {
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] Could not create dummy context\n");
- return FALSE;
- }
- }
-
- if (!(pDRIContextPriv = DRICreateContextPriv(pScreen, pHWContext, 0))) {
- return FALSE;
- }
-
- contextStore = DRIGetContextStore(pDRIContextPriv);
- if (pDRIPriv->pDriverInfo->CreateContext) {
- if (!((*pDRIPriv->pDriverInfo->CreateContext)(pScreen, NULL,
- *pHWContext, NULL,
- (DRIContextType)(long)contextStore))) {
- DRIDestroyContextPriv(pDRIContextPriv);
- return FALSE;
- }
- }
-
- /* track this in case the client dies before cleanup */
- AddResource(context, DRIContextPrivResType, (pointer)pDRIContextPriv);
-
- return TRUE;
-}
-
-Bool
-DRIDestroyContext(ScreenPtr pScreen, XID context)
-{
- FreeResourceByType(context, DRIContextPrivResType, FALSE);
-
- return TRUE;
-}
-
-/* DRIContextPrivDelete is called by the resource manager. */
-Bool
-DRIContextPrivDelete(pointer pResource, XID id)
-{
- DRIContextPrivPtr pDRIContextPriv = (DRIContextPrivPtr)pResource;
- DRIScreenPrivPtr pDRIPriv;
- void *contextStore;
-
- pDRIPriv = DRI_SCREEN_PRIV(pDRIContextPriv->pScreen);
- if (pDRIPriv->pDriverInfo->DestroyContext) {
- contextStore = DRIGetContextStore(pDRIContextPriv);
- pDRIPriv->pDriverInfo->DestroyContext(pDRIContextPriv->pScreen,
- pDRIContextPriv->hwContext,
- (DRIContextType)(long)contextStore);
- }
- return DRIDestroyContextPriv(pDRIContextPriv);
-}
-
-
-/* This walks the drawable timestamp array and invalidates all of them
- * in the case of transition from private to shared backbuffers. It's
- * not necessary for correctness, because DRIClipNotify gets called in
- * time to prevent any conflict, but the transition from
- * shared->private is sometimes missed if we don't do this.
- */
-static void
-DRIClipNotifyAllDrawables(ScreenPtr pScreen)
-{
- int i;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- for( i=0; i < pDRIPriv->pDriverInfo->maxDrawableTableEntry; i++) {
- pDRIPriv->pSAREA->drawableTable[i].stamp = DRIDrawableValidationStamp++;
- }
-}
-
-
-static void
-DRITransitionToSharedBuffers(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
-
- DRIClipNotifyAllDrawables( pScreen );
-
- if (pDRIInfo->TransitionSingleToMulti3D)
- pDRIInfo->TransitionSingleToMulti3D( pScreen );
-}
-
-
-static void
-DRITransitionToPrivateBuffers(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
-
- DRIClipNotifyAllDrawables( pScreen );
-
- if (pDRIInfo->TransitionMultiToSingle3D)
- pDRIInfo->TransitionMultiToSingle3D( pScreen );
-}
-
-
-static void
-DRITransitionTo3d(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
-
- DRIClipNotifyAllDrawables( pScreen );
-
- if (pDRIInfo->TransitionTo3d)
- pDRIInfo->TransitionTo3d( pScreen );
-}
-
-static void
-DRITransitionTo2d(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
-
- DRIClipNotifyAllDrawables( pScreen );
-
- if (pDRIInfo->TransitionTo2d)
- pDRIInfo->TransitionTo2d( pScreen );
-}
-
-
-static int
-DRIDCNTreeTraversal(WindowPtr pWin, pointer data)
-{
- DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
-
- if (pDRIDrawablePriv) {
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (RegionNumRects(&pWin->clipList) > 0) {
- WindowPtr *pDRIWindows = (WindowPtr*)data;
- int i = 0;
-
- while (pDRIWindows[i])
- i++;
-
- pDRIWindows[i] = pWin;
-
- pDRIPriv->nrWalked++;
- }
-
- if (pDRIPriv->nrWindows == pDRIPriv->nrWalked)
- return WT_STOPWALKING;
- }
-
- return WT_WALKCHILDREN;
-}
-
-static void
-DRIDriverClipNotify(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv->pDriverInfo->ClipNotify) {
- WindowPtr *pDRIWindows = calloc(sizeof(WindowPtr), pDRIPriv->nrWindows);
- DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
-
- if (pDRIPriv->nrWindows > 0) {
- pDRIPriv->nrWalked = 0;
- TraverseTree(pScreen->root, DRIDCNTreeTraversal,
- (pointer)pDRIWindows);
- }
-
- pDRIInfo->ClipNotify(pScreen, pDRIWindows, pDRIPriv->nrWindows);
-
- free(pDRIWindows);
- }
-}
-
-static void
-DRIIncreaseNumberVisible(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- switch (++pDRIPriv->nrWindowsVisible) {
- case 1:
- DRITransitionTo3d( pScreen );
- break;
- case 2:
- DRITransitionToSharedBuffers( pScreen );
- break;
- default:
- break;
- }
-
- DRIDriverClipNotify(pScreen);
-}
-
-static void
-DRIDecreaseNumberVisible(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- switch (--pDRIPriv->nrWindowsVisible) {
- case 0:
- DRITransitionTo2d( pScreen );
- break;
- case 1:
- DRITransitionToPrivateBuffers( pScreen );
- break;
- default:
- break;
- }
-
- DRIDriverClipNotify(pScreen);
-}
-
-Bool
-DRICreateDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable,
- drm_drawable_t * hHWDrawable)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv;
- WindowPtr pWin;
-
- if (pDrawable->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr)pDrawable;
- if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
- pDRIDrawablePriv->refCount++;
-
- if (!pDRIDrawablePriv->hwDrawable) {
- drmCreateDrawable(pDRIPriv->drmFD, &pDRIDrawablePriv->hwDrawable);
- }
- }
- else {
- /* allocate a DRI Window Private record */
- if (!(pDRIDrawablePriv = malloc(sizeof(DRIDrawablePrivRec)))) {
- return FALSE;
- }
-
- /* Only create a drm_drawable_t once */
- if (drmCreateDrawable(pDRIPriv->drmFD,
- &pDRIDrawablePriv->hwDrawable)) {
- free(pDRIDrawablePriv);
- return FALSE;
- }
-
- /* add it to the list of DRI drawables for this screen */
- pDRIDrawablePriv->pScreen = pScreen;
- pDRIDrawablePriv->refCount = 1;
- pDRIDrawablePriv->drawableIndex = -1;
- pDRIDrawablePriv->nrects = RegionNumRects(&pWin->clipList);
-
- /* save private off of preallocated index */
- dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey,
- pDRIDrawablePriv);
- pDRIPriv->nrWindows++;
-
- if (pDRIDrawablePriv->nrects)
- DRIIncreaseNumberVisible(pScreen);
- }
-
- /* track this in case the client dies */
- AddResource(FakeClientID(client->index), DRIDrawablePrivResType,
- (pointer)(intptr_t)pDrawable->id);
-
- if (pDRIDrawablePriv->hwDrawable) {
- drmUpdateDrawableInfo(pDRIPriv->drmFD,
- pDRIDrawablePriv->hwDrawable,
- DRM_DRAWABLE_CLIPRECTS,
- RegionNumRects(&pWin->clipList),
- RegionRects(&pWin->clipList));
- *hHWDrawable = pDRIDrawablePriv->hwDrawable;
- }
- }
- else if (pDrawable->type != DRAWABLE_PIXMAP) { /* PBuffer */
- /* NOT_DONE */
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-DRIDrawablePrivDestroy(WindowPtr pWin)
-{
- DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
- ScreenPtr pScreen;
- DRIScreenPrivPtr pDRIPriv;
-
- if (!pDRIDrawablePriv)
- return;
-
- pScreen = pWin->drawable.pScreen;
- pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIDrawablePriv->drawableIndex != -1) {
- /* bump stamp to force outstanding 3D requests to resync */
- pDRIPriv->pSAREA->drawableTable[pDRIDrawablePriv->drawableIndex].stamp
- = DRIDrawableValidationStamp++;
-
- /* release drawable table entry */
- pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
- }
-
- pDRIPriv->nrWindows--;
-
- if (pDRIDrawablePriv->nrects)
- DRIDecreaseNumberVisible(pScreen);
-
- drmDestroyDrawable(pDRIPriv->drmFD, pDRIDrawablePriv->hwDrawable);
-
- free(pDRIDrawablePriv);
- dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
-}
-
-static Bool
-DRIDestroyDrawableCB(pointer value, XID id, pointer data)
-{
- if (value == data) {
- /* This calls back DRIDrawablePrivDelete which frees private area */
- FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-Bool
-DRIDestroyDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable)
-{
- if (pDrawable->type == DRAWABLE_WINDOW) {
- LookupClientResourceComplex(client, DRIDrawablePrivResType,
- DRIDestroyDrawableCB,
- (pointer)(intptr_t)pDrawable->id);
- }
- else { /* pixmap (or for GLX 1.3, a PBuffer) */
- /* NOT_DONE */
- return FALSE;
- }
-
- return TRUE;
-}
-
-Bool
-DRIDrawablePrivDelete(pointer pResource, XID id)
-{
- WindowPtr pWin;
- int rc;
-
- /* For DRIDrawablePrivResType, the XID is the client's fake ID. The
- * important XID is the value in pResource. */
- id = (XID)(intptr_t)pResource;
- rc = dixLookupWindow(&pWin, id, serverClient, DixGetAttrAccess);
-
- if (rc == Success) {
- DRIDrawablePrivPtr pDRIDrwPriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
-
- if (!pDRIDrwPriv)
- return FALSE;
-
- if (--pDRIDrwPriv->refCount == 0)
- DRIDrawablePrivDestroy(pWin);
-
- return TRUE;
- }
- else { /* pixmap (or for GLX 1.3, a PBuffer) */
- /* NOT_DONE */
- return FALSE;
- }
-}
-
-Bool
-DRIGetDrawableInfo(ScreenPtr pScreen,
- DrawablePtr pDrawable,
- unsigned int* index,
- unsigned int* stamp,
- int* X,
- int* Y,
- int* W,
- int* H,
- int* numClipRects,
- drm_clip_rect_t ** pClipRects,
- int* backX,
- int* backY,
- int* numBackClipRects,
- drm_clip_rect_t ** pBackClipRects)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv, pOldDrawPriv;
- WindowPtr pWin, pOldWin;
- int i;
-
-#if 0
- printf("maxDrawableTableEntry = %d\n", pDRIPriv->pDriverInfo->maxDrawableTableEntry);
-#endif
-
- if (pDrawable->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr)pDrawable;
- if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
-
- /* Manage drawable table */
- if (pDRIDrawablePriv->drawableIndex == -1) { /* load SAREA table */
-
- /* Search table for empty entry */
- i = 0;
- while (i < pDRIPriv->pDriverInfo->maxDrawableTableEntry) {
- if (!(pDRIPriv->DRIDrawables[i])) {
- pDRIPriv->DRIDrawables[i] = pDrawable;
- pDRIDrawablePriv->drawableIndex = i;
- pDRIPriv->pSAREA->drawableTable[i].stamp =
- DRIDrawableValidationStamp++;
- break;
- }
- i++;
- }
-
- /* Search table for oldest entry */
- if (i == pDRIPriv->pDriverInfo->maxDrawableTableEntry) {
- unsigned int oldestStamp = ~0;
- int oldestIndex = 0;
- i = pDRIPriv->pDriverInfo->maxDrawableTableEntry;
- while (i--) {
- if (pDRIPriv->pSAREA->drawableTable[i].stamp <
- oldestStamp) {
- oldestIndex = i;
- oldestStamp =
- pDRIPriv->pSAREA->drawableTable[i].stamp;
- }
- }
- pDRIDrawablePriv->drawableIndex = oldestIndex;
-
- /* release oldest drawable table entry */
- pOldWin = (WindowPtr)pDRIPriv->DRIDrawables[oldestIndex];
- pOldDrawPriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pOldWin);
- pOldDrawPriv->drawableIndex = -1;
-
- /* claim drawable table entry */
- pDRIPriv->DRIDrawables[oldestIndex] = pDrawable;
-
- /* validate SAREA entry */
- pDRIPriv->pSAREA->drawableTable[oldestIndex].stamp =
- DRIDrawableValidationStamp++;
-
- /* check for stamp wrap around */
- if (oldestStamp > DRIDrawableValidationStamp) {
-
- /* walk SAREA table and invalidate all drawables */
- for( i=0;
- i < pDRIPriv->pDriverInfo->maxDrawableTableEntry;
- i++) {
- pDRIPriv->pSAREA->drawableTable[i].stamp =
- DRIDrawableValidationStamp++;
- }
- }
- }
-
- /* If the driver wants to be notified when the index is
- * set for a drawable, let it know now.
- */
- if (pDRIPriv->pDriverInfo->SetDrawableIndex)
- pDRIPriv->pDriverInfo->SetDrawableIndex(pWin,
- pDRIDrawablePriv->drawableIndex);
-
- /* reinit drawable ID if window is visible */
- if ((pWin->viewable) &&
- (pDRIPriv->pDriverInfo->bufferRequests != DRI_NO_WINDOWS))
- {
- (*pDRIPriv->pDriverInfo->InitBuffers)(pWin,
- &pWin->clipList, pDRIDrawablePriv->drawableIndex);
- }
- }
-
- *index = pDRIDrawablePriv->drawableIndex;
- *stamp = pDRIPriv->pSAREA->drawableTable[*index].stamp;
- *X = (int)(pWin->drawable.x);
- *Y = (int)(pWin->drawable.y);
- *W = (int)(pWin->drawable.width);
- *H = (int)(pWin->drawable.height);
- *numClipRects = RegionNumRects(&pWin->clipList);
- *pClipRects = (drm_clip_rect_t *)RegionRects(&pWin->clipList);
-
- if (!*numClipRects && pDRIPriv->fullscreen) {
- /* use fake full-screen clip rect */
- pDRIPriv->fullscreen_rect.x1 = *X;
- pDRIPriv->fullscreen_rect.y1 = *Y;
- pDRIPriv->fullscreen_rect.x2 = *X + *W;
- pDRIPriv->fullscreen_rect.y2 = *Y + *H;
-
- *numClipRects = 1;
- *pClipRects = &pDRIPriv->fullscreen_rect;
- }
-
- *backX = *X;
- *backY = *Y;
-
- if (pDRIPriv->nrWindowsVisible == 1 && *numClipRects) {
- /* Use a single cliprect. */
-
- int x0 = *X;
- int y0 = *Y;
- int x1 = x0 + *W;
- int y1 = y0 + *H;
-
- if (x0 < 0) x0 = 0;
- if (y0 < 0) y0 = 0;
- if (x1 > pScreen->width) x1 = pScreen->width;
- if (y1 > pScreen->height) y1 = pScreen->height;
-
- if (y0 >= y1 || x0 >= x1) {
- *numBackClipRects = 0;
- *pBackClipRects = NULL;
- } else {
- pDRIPriv->private_buffer_rect.x1 = x0;
- pDRIPriv->private_buffer_rect.y1 = y0;
- pDRIPriv->private_buffer_rect.x2 = x1;
- pDRIPriv->private_buffer_rect.y2 = y1;
-
- *numBackClipRects = 1;
- *pBackClipRects = &(pDRIPriv->private_buffer_rect);
- }
- } else {
- /* Use the frontbuffer cliprects for back buffers. */
- *numBackClipRects = 0;
- *pBackClipRects = 0;
- }
- }
- else {
- /* Not a DRIDrawable */
- return FALSE;
- }
- }
- else { /* pixmap (or for GLX 1.3, a PBuffer) */
- /* NOT_DONE */
- return FALSE;
- }
-
- return TRUE;
-}
-
-Bool
-DRIGetDeviceInfo(ScreenPtr pScreen,
- drm_handle_t * hFrameBuffer,
- int* fbOrigin,
- int* fbSize,
- int* fbStride,
- int* devPrivateSize,
- void** pDevPrivate)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- *hFrameBuffer = pDRIPriv->pDriverInfo->hFrameBuffer;
- *fbOrigin = 0;
- *fbSize = pDRIPriv->pDriverInfo->frameBufferSize;
- *fbStride = pDRIPriv->pDriverInfo->frameBufferStride;
- *devPrivateSize = pDRIPriv->pDriverInfo->devPrivateSize;
- *pDevPrivate = pDRIPriv->pDriverInfo->devPrivate;
-
- return TRUE;
-}
-
-DRIInfoPtr
-DRICreateInfoRec(void)
-{
- DRIInfoPtr inforec = (DRIInfoPtr)calloc(1, sizeof(DRIInfoRec));
- if (!inforec) return NULL;
-
- /* Initialize defaults */
- inforec->busIdString = NULL;
-
- /* Wrapped function defaults */
- inforec->wrap.WakeupHandler = DRIDoWakeupHandler;
- inforec->wrap.BlockHandler = DRIDoBlockHandler;
- inforec->wrap.WindowExposures = DRIWindowExposures;
- inforec->wrap.CopyWindow = DRICopyWindow;
- inforec->wrap.ValidateTree = DRIValidateTree;
- inforec->wrap.PostValidateTree = DRIPostValidateTree;
- inforec->wrap.ClipNotify = DRIClipNotify;
- inforec->wrap.AdjustFrame = DRIAdjustFrame;
-
- inforec->TransitionTo2d = 0;
- inforec->TransitionTo3d = 0;
- inforec->SetDrawableIndex = 0;
-
- return inforec;
-}
-
-void
-DRIDestroyInfoRec(DRIInfoPtr DRIInfo)
-{
- free(DRIInfo->busIdString);
- free((char*)DRIInfo);
-}
-
-
-void
-DRIWakeupHandler(pointer wakeupData, int result, pointer pReadmask)
-{
- int i;
-
- for (i = 0; i < screenInfo.numScreens; i++) {
- ScreenPtr pScreen = screenInfo.screens[i];
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv &&
- pDRIPriv->pDriverInfo->wrap.WakeupHandler)
- (*pDRIPriv->pDriverInfo->wrap.WakeupHandler)(i, wakeupData,
- result, pReadmask);
- }
-}
-
-void
-DRIBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
-{
- int i;
-
- for (i = 0; i < screenInfo.numScreens; i++) {
- ScreenPtr pScreen = screenInfo.screens[i];
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv &&
- pDRIPriv->pDriverInfo->wrap.BlockHandler)
- (*pDRIPriv->pDriverInfo->wrap.BlockHandler)(i, blockData,
- pTimeout, pReadmask);
- }
-}
-
-void
-DRIDoWakeupHandler(int screenNum, pointer wakeupData,
- unsigned long result, pointer pReadmask)
-{
- ScreenPtr pScreen = screenInfo.screens[screenNum];
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- DRILock(pScreen, 0);
- if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
- /* hide X context by swapping 2D component here */
- (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
- DRI_3D_SYNC,
- DRI_2D_CONTEXT,
- pDRIPriv->partial3DContextStore,
- DRI_2D_CONTEXT,
- pDRIPriv->hiddenContextStore);
- }
-}
-
-void
-DRIDoBlockHandler(int screenNum, pointer blockData,
- pointer pTimeout, pointer pReadmask)
-{
- ScreenPtr pScreen = screenInfo.screens[screenNum];
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
- /* hide X context by swapping 2D component here */
- (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
- DRI_2D_SYNC,
- DRI_NO_CONTEXT,
- NULL,
- DRI_2D_CONTEXT,
- pDRIPriv->partial3DContextStore);
- }
-
- if (pDRIPriv->windowsTouched)
- DRM_SPINUNLOCK(&pDRIPriv->pSAREA->drawable_lock, 1);
- pDRIPriv->windowsTouched = FALSE;
-
- DRIUnlock(pScreen);
-}
-
-void
-DRISwapContext(int drmFD, void *oldctx, void *newctx)
-{
- DRIContextPrivPtr oldContext = (DRIContextPrivPtr)oldctx;
- DRIContextPrivPtr newContext = (DRIContextPrivPtr)newctx;
- ScreenPtr pScreen = newContext->pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- void* oldContextStore = NULL;
- DRIContextType oldContextType;
- void* newContextStore = NULL;
- DRIContextType newContextType;
- DRISyncType syncType;
-#ifdef DEBUG
- static int count = 0;
-
- if (!newContext) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[DRI] Context Switch Error: oldContext=%x, newContext=%x\n",
- oldContext, newContext);
- return;
- }
-
- /* usefull for debugging, just print out after n context switches */
- if (!count || !(count % 1)) {
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[DRI] Context switch %5d from %p/0x%08x (%d)\n",
- count,
- oldContext,
- oldContext ? oldContext->flags : 0,
- oldContext ? oldContext->hwContext : -1);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[DRI] Context switch %5d to %p/0x%08x (%d)\n",
- count,
- newContext,
- newContext ? newContext->flags : 0,
- newContext ? newContext->hwContext : -1);
- }
- ++count;
-#endif
-
- if (!pDRIPriv->pDriverInfo->SwapContext) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[DRI] DDX driver missing context swap call back\n");
- return;
- }
-
- if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
-
- /* only 3D contexts are swapped in this case */
- if (oldContext) {
- oldContextStore = DRIGetContextStore(oldContext);
- oldContext->valid3D = TRUE;
- oldContextType = DRI_3D_CONTEXT;
- } else {
- oldContextType = DRI_NO_CONTEXT;
- }
- newContextStore = DRIGetContextStore(newContext);
- if ((newContext->valid3D) &&
- (newContext->hwContext != pDRIPriv->myContext)) {
- newContextType = DRI_3D_CONTEXT;
- }
- else {
- newContextType = DRI_2D_CONTEXT;
- }
- syncType = DRI_3D_SYNC;
- }
- else /* default: driverSwapMethod == DRI_SERVER_SWAP */ {
-
- /* optimize 2D context swaps */
-
- if (newContext->flags & DRI_CONTEXT_2DONLY) {
- /* go from 3D context to 2D context and only save 2D
- * subset of 3D state
- */
- oldContextStore = DRIGetContextStore(oldContext);
- oldContextType = DRI_2D_CONTEXT;
- newContextStore = DRIGetContextStore(newContext);
- newContextType = DRI_2D_CONTEXT;
- syncType = DRI_3D_SYNC;
- pDRIPriv->lastPartial3DContext = oldContext;
- }
- else if (oldContext->flags & DRI_CONTEXT_2DONLY) {
- if (pDRIPriv->lastPartial3DContext == newContext) {
- /* go from 2D context back to previous 3D context and
- * only restore 2D subset of previous 3D state
- */
- oldContextStore = DRIGetContextStore(oldContext);
- oldContextType = DRI_2D_CONTEXT;
- newContextStore = DRIGetContextStore(newContext);
- newContextType = DRI_2D_CONTEXT;
- syncType = DRI_2D_SYNC;
- }
- else {
- /* go from 2D context to a different 3D context */
-
- /* call DDX driver to do partial restore */
- oldContextStore = DRIGetContextStore(oldContext);
- newContextStore =
- DRIGetContextStore(pDRIPriv->lastPartial3DContext);
- (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
- DRI_2D_SYNC,
- DRI_2D_CONTEXT,
- oldContextStore,
- DRI_2D_CONTEXT,
- newContextStore);
-
- /* now setup for a complete 3D swap */
- oldContextStore = newContextStore;
- oldContext->valid3D = TRUE;
- oldContextType = DRI_3D_CONTEXT;
- newContextStore = DRIGetContextStore(newContext);
- if ((newContext->valid3D) &&
- (newContext->hwContext != pDRIPriv->myContext)) {
- newContextType = DRI_3D_CONTEXT;
- }
- else {
- newContextType = DRI_2D_CONTEXT;
- }
- syncType = DRI_NO_SYNC;
- }
- }
- else {
- /* now setup for a complete 3D swap */
- oldContextStore = newContextStore;
- oldContext->valid3D = TRUE;
- oldContextType = DRI_3D_CONTEXT;
- newContextStore = DRIGetContextStore(newContext);
- if ((newContext->valid3D) &&
- (newContext->hwContext != pDRIPriv->myContext)) {
- newContextType = DRI_3D_CONTEXT;
- }
- else {
- newContextType = DRI_2D_CONTEXT;
- }
- syncType = DRI_3D_SYNC;
- }
- }
-
- /* call DDX driver to perform the swap */
- (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
- syncType,
- oldContextType,
- oldContextStore,
- newContextType,
- newContextStore);
-}
-
-void*
-DRIGetContextStore(DRIContextPrivPtr context)
-{
- return((void *)context->pContextStore);
-}
-
-void
-DRIWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr bsreg)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
-
- if(pDRIDrawablePriv) {
- (*pDRIPriv->pDriverInfo->InitBuffers)(pWin, prgn,
- pDRIDrawablePriv->drawableIndex);
- }
-
- /* call lower wrapped functions */
- if (pDRIPriv && pDRIPriv->wrap.WindowExposures) {
-
- /* unwrap */
- pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
-
- /* call lower layers */
- (*pScreen->WindowExposures)(pWin, prgn, bsreg);
-
- /* rewrap */
- pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
- pScreen->WindowExposures = DRIWindowExposures;
- }
-}
-
-
-static int
-DRITreeTraversal(WindowPtr pWin, pointer data)
-{
- DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
-
- if(pDRIDrawablePriv) {
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if(RegionNumRects(&(pWin->clipList)) > 0) {
- RegionPtr reg = (RegionPtr)data;
-
- RegionUnion(reg, reg, &(pWin->clipList));
- pDRIPriv->nrWalked++;
- }
-
- if(pDRIPriv->nrWindows == pDRIPriv->nrWalked)
- return WT_STOPWALKING;
- }
- return WT_WALKCHILDREN;
-}
-
-Bool
-DRIDestroyWindow(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- Bool retval = TRUE;
-
- DRIDrawablePrivDestroy(pWin);
-
- /* call lower wrapped functions */
- if(pDRIPriv->DestroyWindow) {
- /* unwrap */
- pScreen->DestroyWindow = pDRIPriv->DestroyWindow;
-
- /* call lower layers */
- retval = (*pScreen->DestroyWindow)(pWin);
-
- /* rewrap */
- pDRIPriv->DestroyWindow = pScreen->DestroyWindow;
- pScreen->DestroyWindow = DRIDestroyWindow;
- }
-
- return retval;
-}
-
-void
-DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if(!pDRIPriv) return;
-
- if(pDRIPriv->nrWindowsVisible > 0) {
- RegionRec reg;
-
- RegionNull(&reg);
- pDRIPriv->nrWalked = 0;
- TraverseTree(pWin, DRITreeTraversal, (pointer)(&reg));
-
- if(RegionNotEmpty(&reg)) {
- RegionTranslate(&reg, ptOldOrg.x - pWin->drawable.x,
- ptOldOrg.y - pWin->drawable.y);
- RegionIntersect(&reg, &reg, prgnSrc);
-
- /* The MoveBuffers interface is not ideal */
- (*pDRIPriv->pDriverInfo->MoveBuffers)(pWin, ptOldOrg, &reg,
- pDRIPriv->pDriverInfo->ddxDrawableTableEntry);
- }
-
- RegionUninit(&reg);
- }
-
- /* call lower wrapped functions */
- if(pDRIPriv->wrap.CopyWindow) {
- /* unwrap */
- pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
-
- /* call lower layers */
- (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
-
- /* rewrap */
- pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
- pScreen->CopyWindow = DRICopyWindow;
- }
-}
-
-static void
-DRIGetSecs(long *secs, long *usecs)
-{
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
-
- *secs = tv.tv_sec;
- *usecs = tv.tv_usec;
-}
-
-static unsigned long
-DRIComputeMilliSeconds(unsigned long s_secs, unsigned long s_usecs,
- unsigned long f_secs, unsigned long f_usecs)
-{
- if (f_usecs < s_usecs) {
- --f_secs;
- f_usecs += 1000000;
- }
- return (f_secs - s_secs) * 1000 + (f_usecs - s_usecs) / 1000;
-}
-
-static void
-DRISpinLockTimeout(drmLock *lock, int val, unsigned long timeout /* in mS */)
-{
- int count = 10000;
-#if !defined(__alpha__) && !defined(__powerpc__)
- char ret;
-#else
- int ret;
-#endif
- long s_secs, s_usecs;
- long f_secs, f_usecs;
- long msecs;
- long prev = 0;
-
- DRIGetSecs(&s_secs, &s_usecs);
-
- do {
- DRM_SPINLOCK_COUNT(lock, val, count, ret);
- if (!ret) return; /* Got lock */
- DRIGetSecs(&f_secs, &f_usecs);
- msecs = DRIComputeMilliSeconds(s_secs, s_usecs, f_secs, f_usecs);
- if (msecs - prev < 250) count *= 2; /* Not more than 0.5S */
- } while (msecs < timeout);
-
- /* Didn't get lock, so take it. The worst
- that can happen is that there is some
- garbage written to the wrong part of the
- framebuffer that a refresh will repair.
- That's undesirable, but better than
- locking the server. This should be a
- very rare event. */
- DRM_SPINLOCK_TAKE(lock, val);
-}
-
-static void
-DRILockTree(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if(!pDRIPriv) return;
-
- /* Restore the last known 3D context if the X context is hidden */
- if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
- (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
- DRI_2D_SYNC,
- DRI_NO_CONTEXT,
- NULL,
- DRI_2D_CONTEXT,
- pDRIPriv->partial3DContextStore);
- }
-
- /* Call kernel to release lock */
- DRIUnlock(pScreen);
-
- /* Grab drawable spin lock: a time out between 10 and 30 seconds is
- appropriate, since this should never time out except in the case of
- client death while the lock is being held. The timeout must be
- greater than any reasonable rendering time. */
- DRISpinLockTimeout(&pDRIPriv->pSAREA->drawable_lock, 1, 10000); /*10 secs*/
-
- /* Call kernel flush outstanding buffers and relock */
- DRILock(pScreen, DRM_LOCK_QUIESCENT|DRM_LOCK_FLUSH_ALL);
-
- /* Switch back to our 2D context if the X context is hidden */
- if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
- /* hide X context by swapping 2D component here */
- (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
- DRI_3D_SYNC,
- DRI_2D_CONTEXT,
- pDRIPriv->partial3DContextStore,
- DRI_2D_CONTEXT,
- pDRIPriv->hiddenContextStore);
- }
-}
-
-int
-DRIValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
-{
- ScreenPtr pScreen = pParent->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- int returnValue = 1; /* always return 1, not checked by dix/window.c */
-
- if(!pDRIPriv) return returnValue;
-
- /* call lower wrapped functions */
- if(pDRIPriv->wrap.ValidateTree) {
- /* unwrap */
- pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree;
-
- /* call lower layers */
- returnValue = (*pScreen->ValidateTree)(pParent, pChild, kind);
-
- /* rewrap */
- pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
- pScreen->ValidateTree = DRIValidateTree;
- }
-
- return returnValue;
-}
-
-void
-DRIPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
-{
- ScreenPtr pScreen;
- DRIScreenPrivPtr pDRIPriv;
-
- if (pParent) {
- pScreen = pParent->drawable.pScreen;
- } else {
- pScreen = pChild->drawable.pScreen;
- }
- if(!(pDRIPriv = DRI_SCREEN_PRIV(pScreen))) return;
-
- if (pDRIPriv->wrap.PostValidateTree) {
- /* unwrap */
- pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree;
-
- /* call lower layers */
- (*pScreen->PostValidateTree)(pParent, pChild, kind);
-
- /* rewrap */
- pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
- pScreen->PostValidateTree = DRIPostValidateTree;
- }
-}
-
-void
-DRIClipNotify(WindowPtr pWin, int dx, int dy)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv;
-
- if(!pDRIPriv) return;
-
- if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
- int nrects = RegionNumRects(&pWin->clipList);
-
- if(!pDRIPriv->windowsTouched) {
- DRILockTree(pScreen);
- pDRIPriv->windowsTouched = TRUE;
- }
-
- if (nrects && !pDRIDrawablePriv->nrects)
- DRIIncreaseNumberVisible(pScreen);
- else if (!nrects && pDRIDrawablePriv->nrects)
- DRIDecreaseNumberVisible(pScreen);
- else
- DRIDriverClipNotify(pScreen);
-
- pDRIDrawablePriv->nrects = nrects;
-
- pDRIPriv->pSAREA->drawableTable[pDRIDrawablePriv->drawableIndex].stamp
- = DRIDrawableValidationStamp++;
-
- drmUpdateDrawableInfo(pDRIPriv->drmFD, pDRIDrawablePriv->hwDrawable,
- DRM_DRAWABLE_CLIPRECTS,
- nrects, RegionRects(&pWin->clipList));
- }
-
- /* call lower wrapped functions */
- if(pDRIPriv->wrap.ClipNotify) {
-
- /* unwrap */
- pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
-
- /* call lower layers */
- (*pScreen->ClipNotify)(pWin, dx, dy);
-
- /* rewrap */
- pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
- pScreen->ClipNotify = DRIClipNotify;
- }
-}
-
-CARD32
-DRIGetDrawableIndex(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
- CARD32 index;
-
- if (pDRIDrawablePriv) {
- index = pDRIDrawablePriv->drawableIndex;
- }
- else {
- index = pDRIPriv->pDriverInfo->ddxDrawableTableEntry;
- }
-
- return index;
-}
-
-unsigned int
-DRIGetDrawableStamp(ScreenPtr pScreen, CARD32 drawable_index)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- return pDRIPriv->pSAREA->drawableTable[drawable_index].stamp;
-}
-
-
-void
-DRIPrintDrawableLock(ScreenPtr pScreen, char *msg)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- ErrorF("%s: %d\n", msg, pDRIPriv->pSAREA->drawable_lock.lock);
-}
-
-void
-DRILock(ScreenPtr pScreen, int flags)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
-
- if (!*pDRIPriv->pLockRefCount) {
- DRM_LOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext, flags);
- *pDRIPriv->pLockingContext = pDRIPriv->myContext;
- } else if (*pDRIPriv->pLockingContext != pDRIPriv->myContext) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[DRI] Locking deadlock.\n"
- "\tAlready locked with context %d,\n"
- "\ttrying to lock with context %d.\n",
- pDRIPriv->pLockingContext,
- pDRIPriv->myContext);
- }
- (*pDRIPriv->pLockRefCount)++;
-}
-
-void
-DRIUnlock(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
-
- if (*pDRIPriv->pLockRefCount > 0) {
- if (pDRIPriv->myContext != *pDRIPriv->pLockingContext) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[DRI] Unlocking inconsistency:\n"
- "\tContext %d trying to unlock lock held by context %d\n",
- pDRIPriv->pLockingContext,
- pDRIPriv->myContext);
- }
- (*pDRIPriv->pLockRefCount)--;
- } else {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "DRIUnlock called when not locked.\n");
- return;
- }
- if (! *pDRIPriv->pLockRefCount)
- DRM_UNLOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext);
-}
-
-void *
-DRIGetSAREAPrivate(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- if (!pDRIPriv) return 0;
-
- return (void *)(((char*)pDRIPriv->pSAREA)+sizeof(XF86DRISAREARec));
-}
-
-drm_context_t
-DRIGetContext(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- if (!pDRIPriv) return 0;
-
- return pDRIPriv->myContext;
-}
-
-void
-DRIGetTexOffsetFuncs(ScreenPtr pScreen,
- DRITexOffsetStartProcPtr *texOffsetStartFunc,
- DRITexOffsetFinishProcPtr *texOffsetFinishFunc)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (!pDRIPriv) return;
-
- *texOffsetStartFunc = pDRIPriv->pDriverInfo->texOffsetStart;
- *texOffsetFinishFunc = pDRIPriv->pDriverInfo->texOffsetFinish;
-}
-
-/* This lets get at the unwrapped functions so that they can correctly
- * call the lowerlevel functions, and choose whether they will be
- * called at every level of recursion (eg in validatetree).
- */
-DRIWrappedFuncsRec *
-DRIGetWrappedFuncs(ScreenPtr pScreen)
-{
- return &(DRI_SCREEN_PRIV(pScreen)->wrap);
-}
-
-/* note that this returns the library version, not the protocol version */
-void
-DRIQueryVersion(int *majorVersion,
- int *minorVersion,
- int *patchVersion)
-{
- *majorVersion = DRIINFO_MAJOR_VERSION;
- *minorVersion = DRIINFO_MINOR_VERSION;
- *patchVersion = DRIINFO_PATCH_VERSION;
-}
-
-static void
-_DRIAdjustFrame(ScrnInfoPtr pScrn, DRIScreenPrivPtr pDRIPriv, int x, int y)
-{
- pDRIPriv->pSAREA->frame.x = x;
- pDRIPriv->pSAREA->frame.y = y;
- pDRIPriv->pSAREA->frame.width = pScrn->frameX1 - x + 1;
- pDRIPriv->pSAREA->frame.height = pScrn->frameY1 - y + 1;
-}
-
-void
-DRIAdjustFrame(int scrnIndex, int x, int y, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[scrnIndex];
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- int px, py;
-
- if (!pDRIPriv || !pDRIPriv->pSAREA) {
- DRIDrvMsg(scrnIndex, X_ERROR, "[DRI] No SAREA (%p %p)\n",
- pDRIPriv, pDRIPriv ? pDRIPriv->pSAREA : NULL);
- return;
- }
-
- if (pDRIPriv->fullscreen) {
- /* Fix up frame */
- pScrn->frameX0 = pDRIPriv->pSAREA->frame.x;
- pScrn->frameY0 = pDRIPriv->pSAREA->frame.y;
- pScrn->frameX1 = pScrn->frameX0 + pDRIPriv->pSAREA->frame.width - 1;
- pScrn->frameY1 = pScrn->frameY0 + pDRIPriv->pSAREA->frame.height - 1;
-
- /* Fix up cursor */
- miPointerGetPosition(inputInfo.pointer, &px, &py);
- if (px < pScrn->frameX0) px = pScrn->frameX0;
- if (px > pScrn->frameX1) px = pScrn->frameX1;
- if (py < pScrn->frameY0) py = pScrn->frameY0;
- if (py > pScrn->frameY1) py = pScrn->frameY1;
- pScreen->SetCursorPosition(inputInfo.pointer, pScreen, px, py, TRUE);
- return;
- }
-
- if (pDRIPriv->wrap.AdjustFrame) {
- /* unwrap */
- pScrn->AdjustFrame = pDRIPriv->wrap.AdjustFrame;
- /* call lower layers */
- (*pScrn->AdjustFrame)(scrnIndex, x, y, flags);
- /* rewrap */
- pDRIPriv->wrap.AdjustFrame = pScrn->AdjustFrame;
- pScrn->AdjustFrame = DRIAdjustFrame;
- }
-
- _DRIAdjustFrame(pScrn, pDRIPriv, x, y);
-}
-
-/*
- * DRIMoveBuffersHelper swaps the regions rects in place leaving you
- * a region with the rects in the order that you need to blit them,
- * but it is possibly (likely) an invalid region afterwards. If you
- * need to use the region again for anything you have to call
- * REGION_VALIDATE on it, or better yet, save a copy first.
- */
-
-void
-DRIMoveBuffersHelper(
- ScreenPtr pScreen,
- int dx,
- int dy,
- int *xdir,
- int *ydir,
- RegionPtr reg
-)
-{
- BoxPtr extents, pbox, firstBox, lastBox;
- BoxRec tmpBox;
- int y, nbox;
-
- extents = RegionExtents(reg);
- nbox = RegionNumRects(reg);
- pbox = RegionRects(reg);
-
- if((dy > 0) && (dy < (extents->y2 - extents->y1))) {
- *ydir = -1;
- if(nbox > 1) {
- firstBox = pbox;
- lastBox = pbox + nbox - 1;
- while((unsigned long)firstBox < (unsigned long)lastBox) {
- tmpBox = *firstBox;
- *firstBox = *lastBox;
- *lastBox = tmpBox;
- firstBox++;
- lastBox--;
- }
- }
- } else *ydir = 1;
-
- if((dx > 0) && (dx < (extents->x2 - extents->x1))) {
- *xdir = -1;
- if(nbox > 1) {
- firstBox = lastBox = pbox;
- y = pbox->y1;
- while(--nbox) {
- pbox++;
- if(pbox->y1 == y) lastBox++;
- else {
- while((unsigned long)firstBox < (unsigned long)lastBox) {
- tmpBox = *firstBox;
- *firstBox = *lastBox;
- *lastBox = tmpBox;
- firstBox++;
- lastBox--;
- }
-
- firstBox = lastBox = pbox;
- y = pbox->y1;
- }
- }
- while((unsigned long)firstBox < (unsigned long)lastBox) {
- tmpBox = *firstBox;
- *firstBox = *lastBox;
- *lastBox = tmpBox;
- firstBox++;
- lastBox--;
- }
- }
- } else *xdir = 1;
-
-}
-
-char *
-DRICreatePCIBusID(const struct pci_device * dev)
-{
- char *busID;
-
- if (asprintf(&busID, "pci:%04x:%02x:%02x.%d",
- dev->domain, dev->bus, dev->dev, dev->func) == -1)
- return NULL;
-
- return busID;
-}
-
-static void drmSIGIOHandler(int interrupt, void *closure)
-{
- unsigned long key;
- void *value;
- ssize_t count;
- drm_ctx_t ctx;
- typedef void (*_drmCallback)(int, void *, void *);
- char buf[256];
- drm_context_t old;
- drm_context_t new;
- void *oldctx;
- void *newctx;
- char *pt;
- drmHashEntry *entry;
- void *hash_table;
-
- hash_table = drmGetHashTable();
-
- if (!hash_table) return;
- if (drmHashFirst(hash_table, &key, &value)) {
- entry = value;
- do {
-#if 0
- fprintf(stderr, "Trying %d\n", entry->fd);
-#endif
- if ((count = read(entry->fd, buf, sizeof(buf) - 1)) > 0) {
- buf[count] = '\0';
-#if 0
- fprintf(stderr, "Got %s\n", buf);
-#endif
-
- for (pt = buf; *pt != ' '; ++pt); /* Find first space */
- ++pt;
- old = strtol(pt, &pt, 0);
- new = strtol(pt, NULL, 0);
- oldctx = drmGetContextTag(entry->fd, old);
- newctx = drmGetContextTag(entry->fd, new);
-#if 0
- fprintf(stderr, "%d %d %p %p\n", old, new, oldctx, newctx);
-#endif
- ((_drmCallback)entry->f)(entry->fd, oldctx, newctx);
- ctx.handle = new;
- ioctl(entry->fd, DRM_IOCTL_NEW_CTX, &ctx);
- }
- } while (drmHashNext(hash_table, &key, &value));
- }
-}
-
-
-int drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *))
-{
- drmHashEntry *entry;
-
- entry = drmGetEntry(fd);
- entry->f = f;
-
- return xf86InstallSIGIOHandler(fd, drmSIGIOHandler, 0);
-}
-
-int drmRemoveSIGIOHandler(int fd)
-{
- drmHashEntry *entry = drmGetEntry(fd);
-
- entry->f = NULL;
-
- return xf86RemoveSIGIOHandler(fd);
-}
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+All Rights Reserved.
+
+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, sub license, 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Jens Owen <jens@tungstengraphics.com>
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include <sys/time.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "xf86drm.h"
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#define _XF86DRI_SERVER_
+#include <X11/dri/xf86driproto.h>
+#include "swaprep.h"
+#include "xf86str.h"
+#include "dri.h"
+#include "sarea.h"
+#include "dristruct.h"
+#include "mi.h"
+#include "mipointer.h"
+#include "xf86_OSproc.h"
+#include "inputstr.h"
+#include "xf86VGAarbiter.h"
+
+static int DRIEntPrivIndex = -1;
+static DevPrivateKeyRec DRIScreenPrivKeyRec;
+#define DRIScreenPrivKey (&DRIScreenPrivKeyRec)
+static DevPrivateKeyRec DRIWindowPrivKeyRec;
+#define DRIWindowPrivKey (&DRIWindowPrivKeyRec)
+static unsigned long DRIGeneration = 0;
+static unsigned int DRIDrawableValidationStamp = 0;
+
+static RESTYPE DRIDrawablePrivResType;
+static RESTYPE DRIContextPrivResType;
+static void DRIDestroyDummyContext(ScreenPtr pScreen, Bool hasCtxPriv);
+
+drmServerInfo DRIDRMServerInfo;
+
+ /* Wrapper just like xf86DrvMsg, but
+ without the verbosity level checking.
+ This will make it easy to turn off some
+ messages later, based on verbosity
+ level. */
+
+/*
+ * Since we're already referencing things from the XFree86 common layer in
+ * this file, we'd might as well just call xf86VDrvMsgVerb, and have
+ * consistent message formatting. The verbosity of these messages can be
+ * easily changed here.
+ */
+#define DRI_MSG_VERBOSITY 1
+static void
+DRIDrvMsg(int scrnIndex, MessageType type, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xf86VDrvMsgVerb(scrnIndex, type, DRI_MSG_VERBOSITY, format, ap);
+ va_end(ap);
+}
+
+
+static void
+DRIOpenDRMCleanup(DRIEntPrivPtr pDRIEntPriv)
+{
+ if (pDRIEntPriv->pLSAREA != NULL) {
+ drmUnmap(pDRIEntPriv->pLSAREA, pDRIEntPriv->sAreaSize);
+ pDRIEntPriv->pLSAREA = NULL;
+ }
+ if (pDRIEntPriv->hLSAREA != 0) {
+ drmRmMap(pDRIEntPriv->drmFD, pDRIEntPriv->hLSAREA);
+ }
+ if (pDRIEntPriv->drmFD >= 0) {
+ drmClose(pDRIEntPriv->drmFD);
+ pDRIEntPriv->drmFD = 0;
+ }
+}
+
+int
+DRIMasterFD(ScrnInfoPtr pScrn)
+{
+ return DRI_ENT_PRIV(pScrn)->drmFD;
+}
+
+void *
+DRIMasterSareaPointer(ScrnInfoPtr pScrn)
+{
+ return DRI_ENT_PRIV(pScrn)->pLSAREA;
+}
+
+drm_handle_t
+DRIMasterSareaHandle(ScrnInfoPtr pScrn)
+{
+ return DRI_ENT_PRIV(pScrn)->hLSAREA;
+}
+
+
+Bool
+DRIOpenDRMMaster(ScrnInfoPtr pScrn,
+ unsigned long sAreaSize,
+ const char *busID,
+ const char *drmDriverName)
+{
+ drmSetVersion saveSv, sv;
+ Bool drmWasAvailable;
+ DRIEntPrivPtr pDRIEntPriv;
+ DRIEntPrivRec tmp;
+ drmVersionPtr drmlibv;
+ int drmlibmajor, drmlibminor;
+ const char *openBusID;
+ int count;
+ int err;
+
+ if (DRIEntPrivIndex == -1)
+ DRIEntPrivIndex = xf86AllocateEntityPrivateIndex();
+
+ pDRIEntPriv = DRI_ENT_PRIV(pScrn);
+
+ if (pDRIEntPriv && pDRIEntPriv->drmFD != -1)
+ return TRUE;
+
+ drmWasAvailable = drmAvailable();
+
+ memset(&tmp, 0, sizeof(tmp));
+
+ /* Check the DRM lib version.
+ * drmGetLibVersion was not supported in version 1.0, so check for
+ * symbol first to avoid possible crash or hang.
+ */
+
+ drmlibmajor = 1;
+ drmlibminor = 0;
+ if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
+ drmlibv = drmGetLibVersion(-1);
+ if (drmlibv != NULL) {
+ drmlibmajor = drmlibv->version_major;
+ drmlibminor = drmlibv->version_minor;
+ drmFreeVersion(drmlibv);
+ }
+ }
+
+ /* Check if the libdrm can handle falling back to loading based on name
+ * if a busid string is passed.
+ */
+ openBusID = (drmlibmajor == 1 && drmlibminor >= 2) ? busID : NULL;
+
+ tmp.drmFD = -1;
+ sv.drm_di_major = 1;
+ sv.drm_di_minor = 1;
+ sv.drm_dd_major = -1;
+
+ saveSv = sv;
+ count = 10;
+ while (count--) {
+ tmp.drmFD = drmOpen(drmDriverName, openBusID);
+
+ if (tmp.drmFD < 0) {
+ DRIDrvMsg(-1, X_ERROR, "[drm] drmOpen failed.\n");
+ goto out_err;
+ }
+
+ err = drmSetInterfaceVersion(tmp.drmFD, &sv);
+
+ if (err != -EPERM)
+ break;
+
+ sv = saveSv;
+ drmClose(tmp.drmFD);
+ tmp.drmFD = -1;
+ usleep(100000);
+ }
+
+ if (tmp.drmFD <= 0) {
+ DRIDrvMsg(-1, X_ERROR, "[drm] DRM was busy with another master.\n");
+ goto out_err;
+ }
+
+ if (!drmWasAvailable) {
+ DRIDrvMsg(-1, X_INFO,
+ "[drm] loaded kernel module for \"%s\" driver.\n",
+ drmDriverName);
+ }
+
+ if (err != 0) {
+ sv.drm_di_major = 1;
+ sv.drm_di_minor = 0;
+ }
+
+ DRIDrvMsg(-1, X_INFO, "[drm] DRM interface version %d.%d\n",
+ sv.drm_di_major, sv.drm_di_minor);
+
+ if (sv.drm_di_major == 1 && sv.drm_di_minor >= 1)
+ err = 0;
+ else
+ err = drmSetBusid(tmp.drmFD, busID);
+
+ if (err) {
+ DRIDrvMsg(-1, X_ERROR, "[drm] Could not set DRM device bus ID.\n");
+ goto out_err;
+ }
+
+ /*
+ * Create a lock-containing sarea.
+ */
+
+ if (drmAddMap( tmp.drmFD, 0, sAreaSize, DRM_SHM,
+ DRM_CONTAINS_LOCK, &tmp.hLSAREA) < 0) {
+ DRIDrvMsg(-1, X_INFO, "[drm] Could not create SAREA for DRM lock.\n");
+ tmp.hLSAREA = 0;
+ goto out_err;
+ }
+
+ if (drmMap( tmp.drmFD, tmp.hLSAREA, sAreaSize,
+ (drmAddressPtr)(&tmp.pLSAREA)) < 0) {
+ DRIDrvMsg(-1, X_INFO, "[drm] Mapping SAREA for DRM lock failed.\n");
+ tmp.pLSAREA = NULL;
+ goto out_err;
+ }
+
+ memset(tmp.pLSAREA, 0, sAreaSize);
+
+ /*
+ * Reserved contexts are handled by the first opened screen.
+ */
+
+ tmp.resOwner = NULL;
+
+ if (!pDRIEntPriv)
+ pDRIEntPriv = xnfcalloc(sizeof(*pDRIEntPriv), 1);
+
+ if (!pDRIEntPriv) {
+ DRIDrvMsg(-1, X_INFO, "[drm] Failed to allocate memory for "
+ "DRM device.\n");
+ goto out_err;
+ }
+ *pDRIEntPriv = tmp;
+ xf86GetEntityPrivate((pScrn)->entityList[0],DRIEntPrivIndex)->ptr =
+ pDRIEntPriv;
+
+ DRIDrvMsg(-1, X_INFO, "[drm] DRM open master succeeded.\n");
+ return TRUE;
+
+ out_err:
+
+ DRIOpenDRMCleanup(&tmp);
+ return FALSE;
+}
+
+static void
+DRIClipNotifyAllDrawables(ScreenPtr pScreen);
+
+static void
+dri_crtc_notify(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIClipNotifyAllDrawables(pScreen);
+ xf86_unwrap_crtc_notify(pScreen, pDRIPriv->xf86_crtc_notify);
+ xf86_crtc_notify(pScreen);
+ pDRIPriv->xf86_crtc_notify = xf86_wrap_crtc_notify(pScreen, dri_crtc_notify);
+}
+
+Bool
+DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
+{
+ DRIScreenPrivPtr pDRIPriv;
+ drm_context_t * reserved;
+ int reserved_count;
+ int i;
+ DRIEntPrivPtr pDRIEntPriv;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ DRIContextFlags flags = 0;
+ DRIContextPrivPtr pDRIContextPriv;
+
+ /* If the DRI extension is disabled, do not initialize the DRI */
+ if (noXFree86DRIExtension) {
+ DRIDrvMsg(pScreen->myNum, X_WARNING,
+ "Direct rendering has been disabled.\n");
+ return FALSE;
+ }
+
+ if (!xf86VGAarbiterAllowDRI(pScreen)) {
+ DRIDrvMsg(pScreen->myNum, X_WARNING,
+ "Direct rendering is not supported when VGA arb is necessary for the device\n");
+ return FALSE;
+ }
+
+#ifdef PANORAMIX
+ /*
+ * If Xinerama is on, don't allow DRI to initialise. It won't be usable
+ * anyway.
+ */
+ if (!noPanoramiXExtension) {
+ DRIDrvMsg(pScreen->myNum, X_WARNING,
+ "Direct rendering is not supported when Xinerama is enabled\n");
+ return FALSE;
+ }
+#endif
+
+ if (!DRIOpenDRMMaster(pScrn, pDRIInfo->SAREASize,
+ pDRIInfo->busIdString,
+ pDRIInfo->drmDriverName))
+ return FALSE;
+
+ pDRIEntPriv = DRI_ENT_PRIV(pScrn);
+
+ if (DRIGeneration != serverGeneration)
+ DRIGeneration = serverGeneration;
+
+ if (!dixRegisterPrivateKey(&DRIScreenPrivKeyRec, PRIVATE_SCREEN, 0))
+ return FALSE;
+ if (!dixRegisterPrivateKey(&DRIWindowPrivKeyRec, PRIVATE_WINDOW, 0))
+ return FALSE;
+
+ pDRIPriv = (DRIScreenPrivPtr) calloc(1, sizeof(DRIScreenPrivRec));
+ if (!pDRIPriv) {
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
+ return FALSE;
+ }
+
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, pDRIPriv);
+ pDRIPriv->drmFD = pDRIEntPriv->drmFD;
+ pDRIPriv->directRenderingSupport = TRUE;
+ pDRIPriv->pDriverInfo = pDRIInfo;
+ pDRIPriv->nrWindows = 0;
+ pDRIPriv->nrWindowsVisible = 0;
+ pDRIPriv->fullscreen = NULL;
+
+ pDRIPriv->createDummyCtx = pDRIInfo->createDummyCtx;
+ pDRIPriv->createDummyCtxPriv = pDRIInfo->createDummyCtxPriv;
+
+ pDRIPriv->grabbedDRILock = FALSE;
+ pDRIPriv->drmSIGIOHandlerInstalled = FALSE;
+ *pDRMFD = pDRIPriv->drmFD;
+
+ if (pDRIEntPriv->sAreaGrabbed || pDRIInfo->allocSarea) {
+
+ if (drmAddMap( pDRIPriv->drmFD,
+ 0,
+ pDRIPriv->pDriverInfo->SAREASize,
+ DRM_SHM,
+ 0,
+ &pDRIPriv->hSAREA) < 0)
+ {
+ pDRIPriv->directRenderingSupport = FALSE;
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
+ drmClose(pDRIPriv->drmFD);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] drmAddMap failed\n");
+ return FALSE;
+ }
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] added %d byte SAREA at %p\n",
+ pDRIPriv->pDriverInfo->SAREASize, pDRIPriv->hSAREA);
+
+ /* Backwards compat. */
+ if (drmMap( pDRIPriv->drmFD,
+ pDRIPriv->hSAREA,
+ pDRIPriv->pDriverInfo->SAREASize,
+ (drmAddressPtr)(&pDRIPriv->pSAREA)) < 0)
+ {
+ pDRIPriv->directRenderingSupport = FALSE;
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
+ drmClose(pDRIPriv->drmFD);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] drmMap failed\n");
+ return FALSE;
+ }
+ DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] mapped SAREA %p to %p\n",
+ pDRIPriv->hSAREA, pDRIPriv->pSAREA);
+ memset(pDRIPriv->pSAREA, 0, pDRIPriv->pDriverInfo->SAREASize);
+ } else {
+ DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] Using the DRM lock "
+ "SAREA also for drawables.\n");
+ pDRIPriv->hSAREA = pDRIEntPriv->hLSAREA;
+ pDRIPriv->pSAREA = (XF86DRISAREAPtr) pDRIEntPriv->pLSAREA;
+ pDRIEntPriv->sAreaGrabbed = TRUE;
+ }
+
+ pDRIPriv->hLSAREA = pDRIEntPriv->hLSAREA;
+ pDRIPriv->pLSAREA = pDRIEntPriv->pLSAREA;
+
+ if (!pDRIPriv->pDriverInfo->dontMapFrameBuffer)
+ {
+ if (drmAddMap( pDRIPriv->drmFD,
+ (uintptr_t)pDRIPriv->pDriverInfo->frameBufferPhysicalAddress,
+ pDRIPriv->pDriverInfo->frameBufferSize,
+ DRM_FRAME_BUFFER,
+ 0,
+ &pDRIPriv->pDriverInfo->hFrameBuffer) < 0)
+ {
+ pDRIPriv->directRenderingSupport = FALSE;
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
+ drmUnmap(pDRIPriv->pSAREA, pDRIPriv->pDriverInfo->SAREASize);
+ drmClose(pDRIPriv->drmFD);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] drmAddMap failed\n");
+ return FALSE;
+ }
+ DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] framebuffer handle = %p\n",
+ pDRIPriv->pDriverInfo->hFrameBuffer);
+ } else {
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] framebuffer mapped by ddx driver\n");
+ }
+
+ if (pDRIEntPriv->resOwner == NULL) {
+ pDRIEntPriv->resOwner = pScreen;
+
+ /* Add tags for reserved contexts */
+ if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
+ &reserved_count))) {
+ int i;
+ void *tag;
+
+ for (i = 0; i < reserved_count; i++) {
+ tag = DRICreateContextPrivFromHandle(pScreen,
+ reserved[i],
+ DRI_CONTEXT_RESERVED);
+ drmAddContextTag(pDRIPriv->drmFD, reserved[i], tag);
+ }
+ drmFreeReservedContextList(reserved);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] added %d reserved context%s for kernel\n",
+ reserved_count, reserved_count > 1 ? "s" : "");
+ }
+ }
+
+ /* validate max drawable table entry set by driver */
+ if ((pDRIPriv->pDriverInfo->maxDrawableTableEntry <= 0) ||
+ (pDRIPriv->pDriverInfo->maxDrawableTableEntry > SAREA_MAX_DRAWABLES)) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "Invalid max drawable table size set by driver: %d\n",
+ pDRIPriv->pDriverInfo->maxDrawableTableEntry);
+ }
+
+ /* Initialize drawable tables (screen private and SAREA) */
+ for( i=0; i < pDRIPriv->pDriverInfo->maxDrawableTableEntry; i++) {
+ pDRIPriv->DRIDrawables[i] = NULL;
+ pDRIPriv->pSAREA->drawableTable[i].stamp = 0;
+ pDRIPriv->pSAREA->drawableTable[i].flags = 0;
+ }
+
+ pDRIPriv->pLockRefCount = &pDRIEntPriv->lockRefCount;
+ pDRIPriv->pLockingContext = &pDRIEntPriv->lockingContext;
+
+ if (!pDRIEntPriv->keepFDOpen)
+ pDRIEntPriv->keepFDOpen = pDRIInfo->keepFDOpen;
+
+ pDRIEntPriv->refCount++;
+
+ /* Set up flags for DRICreateContextPriv */
+ switch (pDRIInfo->driverSwapMethod) {
+ case DRI_KERNEL_SWAP:
+ flags = DRI_CONTEXT_2DONLY;
+ break;
+ case DRI_HIDE_X_CONTEXT:
+ flags = DRI_CONTEXT_PRESERVED;
+ break;
+ }
+
+ if (!(pDRIContextPriv = DRICreateContextPriv(pScreen,
+ &pDRIPriv->myContext,
+ flags))) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "failed to create server context\n");
+ return FALSE;
+ }
+ pDRIPriv->myContextPriv = pDRIContextPriv;
+
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "X context handle = %p\n", pDRIPriv->myContext);
+
+ /* Now that we have created the X server's context, we can grab the
+ * hardware lock for the X server.
+ */
+ DRILock(pScreen, 0);
+ pDRIPriv->grabbedDRILock = TRUE;
+
+ /* pointers so that we can prevent memory leaks later */
+ pDRIPriv->hiddenContextStore = NULL;
+ pDRIPriv->partial3DContextStore = NULL;
+
+ switch(pDRIInfo->driverSwapMethod) {
+ case DRI_HIDE_X_CONTEXT:
+ /* Server will handle 3D swaps, and hide 2D swaps from kernel.
+ * Register server context as a preserved context.
+ */
+
+ /* allocate memory for hidden context store */
+ pDRIPriv->hiddenContextStore
+ = (void *)calloc(1, pDRIInfo->contextSize);
+ if (!pDRIPriv->hiddenContextStore) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "failed to allocate hidden context\n");
+ DRIDestroyContextPriv(pDRIContextPriv);
+ return FALSE;
+ }
+
+ /* allocate memory for partial 3D context store */
+ pDRIPriv->partial3DContextStore
+ = (void *)calloc(1, pDRIInfo->contextSize);
+ if (!pDRIPriv->partial3DContextStore) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI] failed to allocate partial 3D context\n");
+ free(pDRIPriv->hiddenContextStore);
+ DRIDestroyContextPriv(pDRIContextPriv);
+ return FALSE;
+ }
+
+ /* save initial context store */
+ if (pDRIInfo->SwapContext) {
+ (*pDRIInfo->SwapContext)(
+ pScreen,
+ DRI_NO_SYNC,
+ DRI_2D_CONTEXT,
+ pDRIPriv->hiddenContextStore,
+ DRI_NO_CONTEXT,
+ NULL);
+ }
+ /* fall through */
+
+ case DRI_SERVER_SWAP:
+ /* For swap methods of DRI_SERVER_SWAP and DRI_HIDE_X_CONTEXT
+ * setup signal handler for receiving swap requests from kernel
+ */
+ if (!(pDRIPriv->drmSIGIOHandlerInstalled =
+ drmInstallSIGIOHandler(pDRIPriv->drmFD, DRISwapContext))) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] failed to setup DRM signal handler\n");
+ free(pDRIPriv->hiddenContextStore);
+ free(pDRIPriv->partial3DContextStore);
+ DRIDestroyContextPriv(pDRIContextPriv);
+ return FALSE;
+ } else {
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] installed DRM signal handler\n");
+ }
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+Bool
+DRIFinishScreenInit(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
+ /* Wrap DRI support */
+ if (pDRIInfo->wrap.ValidateTree) {
+ pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
+ pScreen->ValidateTree = pDRIInfo->wrap.ValidateTree;
+ }
+ if (pDRIInfo->wrap.PostValidateTree) {
+ pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
+ pScreen->PostValidateTree = pDRIInfo->wrap.PostValidateTree;
+ }
+ if (pDRIInfo->wrap.WindowExposures) {
+ pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
+ pScreen->WindowExposures = pDRIInfo->wrap.WindowExposures;
+ }
+
+ pDRIPriv->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = DRIDestroyWindow;
+
+ pDRIPriv->xf86_crtc_notify = xf86_wrap_crtc_notify(pScreen,
+ dri_crtc_notify);
+
+ if (pDRIInfo->wrap.CopyWindow) {
+ pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
+ pScreen->CopyWindow = pDRIInfo->wrap.CopyWindow;
+ }
+ if (pDRIInfo->wrap.ClipNotify) {
+ pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
+ pScreen->ClipNotify = pDRIInfo->wrap.ClipNotify;
+ }
+ if (pDRIInfo->wrap.AdjustFrame) {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ pDRIPriv->wrap.AdjustFrame = pScrn->AdjustFrame;
+ pScrn->AdjustFrame = pDRIInfo->wrap.AdjustFrame;
+ }
+ pDRIPriv->wrapped = TRUE;
+
+ DRIDrvMsg(pScreen->myNum, X_INFO, "[DRI] installation complete\n");
+
+ return TRUE;
+}
+
+void
+DRICloseScreen(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo;
+ drm_context_t * reserved;
+ int reserved_count;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ DRIEntPrivPtr pDRIEntPriv = DRI_ENT_PRIV(pScrn);
+ Bool closeMaster;
+
+ if (pDRIPriv) {
+
+ pDRIInfo = pDRIPriv->pDriverInfo;
+
+ if (pDRIPriv->wrapped) {
+ /* Unwrap DRI Functions */
+ if (pDRIInfo->wrap.ValidateTree) {
+ pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree;
+ pDRIPriv->wrap.ValidateTree = NULL;
+ }
+ if (pDRIInfo->wrap.PostValidateTree) {
+ pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree;
+ pDRIPriv->wrap.PostValidateTree = NULL;
+ }
+ if (pDRIInfo->wrap.WindowExposures) {
+ pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
+ pDRIPriv->wrap.WindowExposures = NULL;
+ }
+ if (pDRIPriv->DestroyWindow) {
+ pScreen->DestroyWindow = pDRIPriv->DestroyWindow;
+ pDRIPriv->DestroyWindow = NULL;
+ }
+
+ xf86_unwrap_crtc_notify(pScreen, pDRIPriv->xf86_crtc_notify);
+
+ if (pDRIInfo->wrap.CopyWindow) {
+ pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
+ pDRIPriv->wrap.CopyWindow = NULL;
+ }
+ if (pDRIInfo->wrap.ClipNotify) {
+ pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
+ pDRIPriv->wrap.ClipNotify = NULL;
+ }
+ if (pDRIInfo->wrap.AdjustFrame) {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ pScrn->AdjustFrame = pDRIPriv->wrap.AdjustFrame;
+ pDRIPriv->wrap.AdjustFrame = NULL;
+ }
+
+ pDRIPriv->wrapped = FALSE;
+ }
+
+ if (pDRIPriv->drmSIGIOHandlerInstalled) {
+ if (!drmRemoveSIGIOHandler(pDRIPriv->drmFD)) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] failed to remove DRM signal handler\n");
+ }
+ }
+
+ if (pDRIPriv->dummyCtxPriv && pDRIPriv->createDummyCtx) {
+ DRIDestroyDummyContext(pScreen, pDRIPriv->createDummyCtxPriv);
+ }
+
+ if (!DRIDestroyContextPriv(pDRIPriv->myContextPriv)) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "failed to destroy server context\n");
+ }
+
+ /* Remove tags for reserved contexts */
+ if (pDRIEntPriv->resOwner == pScreen) {
+ pDRIEntPriv->resOwner = NULL;
+
+ if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
+ &reserved_count))) {
+ int i;
+
+ for (i = 0; i < reserved_count; i++) {
+ DRIDestroyContextPriv(drmGetContextTag(pDRIPriv->drmFD,
+ reserved[i]));
+ }
+ drmFreeReservedContextList(reserved);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] removed %d reserved context%s for kernel\n",
+ reserved_count, reserved_count > 1 ? "s" : "");
+ }
+ }
+
+ /* Make sure signals get unblocked etc. */
+ drmUnlock(pDRIPriv->drmFD, pDRIPriv->myContext);
+ pDRIPriv->pLockRefCount = NULL;
+ closeMaster = (--pDRIEntPriv->refCount == 0) &&
+ !pDRIEntPriv->keepFDOpen;
+ if (closeMaster || pDRIPriv->hSAREA != pDRIEntPriv->hLSAREA) {
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] unmapping %d bytes of SAREA %p at %p\n",
+ pDRIInfo->SAREASize,
+ pDRIPriv->hSAREA,
+ pDRIPriv->pSAREA);
+ if (drmUnmap(pDRIPriv->pSAREA, pDRIInfo->SAREASize)) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] unable to unmap %d bytes"
+ " of SAREA %p at %p\n",
+ pDRIInfo->SAREASize,
+ pDRIPriv->hSAREA,
+ pDRIPriv->pSAREA);
+ }
+ } else {
+ pDRIEntPriv->sAreaGrabbed = FALSE;
+ }
+
+ if (closeMaster || (pDRIEntPriv->drmFD != pDRIPriv->drmFD)) {
+ drmClose(pDRIPriv->drmFD);
+ if (pDRIEntPriv->drmFD == pDRIPriv->drmFD) {
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Closed DRM master.\n");
+ pDRIEntPriv->drmFD = -1;
+ }
+ }
+
+ free(pDRIPriv);
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
+ }
+}
+
+#define DRM_MSG_VERBOSITY 3
+
+static int dri_drm_debug_print(const char *format, va_list ap)
+{
+ xf86VDrvMsgVerb(-1, X_NONE, DRM_MSG_VERBOSITY, format, ap);
+ return 0;
+}
+
+static void dri_drm_get_perms(gid_t *group, mode_t *mode)
+{
+ *group = xf86ConfigDRI.group;
+ *mode = xf86ConfigDRI.mode;
+}
+
+drmServerInfo DRIDRMServerInfo = {
+ dri_drm_debug_print,
+ xf86LoadKernelModule,
+ dri_drm_get_perms,
+};
+
+Bool
+DRIExtensionInit(void)
+{
+ if (DRIGeneration != serverGeneration) {
+ return FALSE;
+ }
+
+ DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete,
+ "DRIDrawable");
+ DRIContextPrivResType = CreateNewResourceType(DRIContextPrivDelete,
+ "DRIContext");
+
+ if (!DRIDrawablePrivResType || !DRIContextPrivResType)
+ return FALSE;
+
+ RegisterBlockAndWakeupHandlers(DRIBlockHandler, DRIWakeupHandler, NULL);
+
+ return TRUE;
+}
+
+void
+DRIReset(void)
+{
+ /*
+ * This stub routine is called when the X Server recycles, resources
+ * allocated by DRIExtensionInit need to be managed here.
+ *
+ * Currently this routine is a stub because all the interesting resources
+ * are managed via the screen init process.
+ */
+}
+
+Bool
+DRIQueryDirectRenderingCapable(ScreenPtr pScreen, Bool* isCapable)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIPriv)
+ *isCapable = pDRIPriv->directRenderingSupport;
+ else
+ *isCapable = FALSE;
+
+ return TRUE;
+}
+
+Bool
+DRIOpenConnection(ScreenPtr pScreen, drm_handle_t * hSAREA, char **busIdString)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ *hSAREA = pDRIPriv->hSAREA;
+ *busIdString = pDRIPriv->pDriverInfo->busIdString;
+
+ return TRUE;
+}
+
+Bool
+DRIAuthConnection(ScreenPtr pScreen, drm_magic_t magic)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (drmAuthMagic(pDRIPriv->drmFD, magic)) return FALSE;
+ return TRUE;
+}
+
+Bool
+DRICloseConnection(ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+Bool
+DRIGetClientDriverName(ScreenPtr pScreen,
+ int *ddxDriverMajorVersion,
+ int *ddxDriverMinorVersion,
+ int *ddxDriverPatchVersion,
+ char **clientDriverName)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ *ddxDriverMajorVersion = pDRIPriv->pDriverInfo->ddxDriverMajorVersion;
+ *ddxDriverMinorVersion = pDRIPriv->pDriverInfo->ddxDriverMinorVersion;
+ *ddxDriverPatchVersion = pDRIPriv->pDriverInfo->ddxDriverPatchVersion;
+ *clientDriverName = pDRIPriv->pDriverInfo->clientDriverName;
+
+ return TRUE;
+}
+
+/* DRICreateContextPriv and DRICreateContextPrivFromHandle are helper
+ functions that layer on drmCreateContext and drmAddContextTag.
+
+ DRICreateContextPriv always creates a kernel drm_context_t and then calls
+ DRICreateContextPrivFromHandle to create a DRIContextPriv structure for
+ DRI tracking. For the SIGIO handler, the drm_context_t is associated with
+ DRIContextPrivPtr. Any special flags are stored in the DRIContextPriv
+ area and are passed to the kernel (if necessary).
+
+ DRICreateContextPriv returns a pointer to newly allocated
+ DRIContextPriv, and returns the kernel drm_context_t in pHWContext. */
+
+DRIContextPrivPtr
+DRICreateContextPriv(ScreenPtr pScreen,
+ drm_context_t * pHWContext,
+ DRIContextFlags flags)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (drmCreateContext(pDRIPriv->drmFD, pHWContext)) {
+ return NULL;
+ }
+
+ return DRICreateContextPrivFromHandle(pScreen, *pHWContext, flags);
+}
+
+DRIContextPrivPtr
+DRICreateContextPrivFromHandle(ScreenPtr pScreen,
+ drm_context_t hHWContext,
+ DRIContextFlags flags)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIContextPrivPtr pDRIContextPriv;
+ int contextPrivSize;
+
+ contextPrivSize = sizeof(DRIContextPrivRec) +
+ pDRIPriv->pDriverInfo->contextSize;
+ if (!(pDRIContextPriv = calloc(1, contextPrivSize))) {
+ return NULL;
+ }
+ pDRIContextPriv->pContextStore = (void *)(pDRIContextPriv + 1);
+
+ drmAddContextTag(pDRIPriv->drmFD, hHWContext, pDRIContextPriv);
+
+ pDRIContextPriv->hwContext = hHWContext;
+ pDRIContextPriv->pScreen = pScreen;
+ pDRIContextPriv->flags = flags;
+ pDRIContextPriv->valid3D = FALSE;
+
+ if (flags & DRI_CONTEXT_2DONLY) {
+ if (drmSetContextFlags(pDRIPriv->drmFD,
+ hHWContext,
+ DRM_CONTEXT_2DONLY)) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] failed to set 2D context flag\n");
+ DRIDestroyContextPriv(pDRIContextPriv);
+ return NULL;
+ }
+ }
+ if (flags & DRI_CONTEXT_PRESERVED) {
+ if (drmSetContextFlags(pDRIPriv->drmFD,
+ hHWContext,
+ DRM_CONTEXT_PRESERVED)) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] failed to set preserved flag\n");
+ DRIDestroyContextPriv(pDRIContextPriv);
+ return NULL;
+ }
+ }
+ return pDRIContextPriv;
+}
+
+Bool
+DRIDestroyContextPriv(DRIContextPrivPtr pDRIContextPriv)
+{
+ DRIScreenPrivPtr pDRIPriv;
+
+ if (!pDRIContextPriv) return TRUE;
+
+ pDRIPriv = DRI_SCREEN_PRIV(pDRIContextPriv->pScreen);
+
+ if (!(pDRIContextPriv->flags & DRI_CONTEXT_RESERVED)) {
+ /* Don't delete reserved contexts from
+ kernel area -- the kernel manages its
+ reserved contexts itself. */
+ if (drmDestroyContext(pDRIPriv->drmFD, pDRIContextPriv->hwContext))
+ return FALSE;
+ }
+
+ /* Remove the tag last to prevent a race
+ condition where the context has pending
+ buffers. The context can't be re-used
+ while in this thread, but buffers can be
+ dispatched asynchronously. */
+ drmDelContextTag(pDRIPriv->drmFD, pDRIContextPriv->hwContext);
+ free(pDRIContextPriv);
+ return TRUE;
+}
+
+static Bool
+DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIContextPrivPtr pDRIContextPriv;
+ void *contextStore;
+
+ if (!(pDRIContextPriv =
+ DRICreateContextPriv(pScreen,
+ &pDRIPriv->pSAREA->dummy_context, 0))) {
+ return FALSE;
+ }
+
+ contextStore = DRIGetContextStore(pDRIContextPriv);
+ if (pDRIPriv->pDriverInfo->CreateContext && needCtxPriv) {
+ if (!pDRIPriv->pDriverInfo->CreateContext(pScreen, NULL,
+ pDRIPriv->pSAREA->dummy_context,
+ NULL,
+ (DRIContextType)(long)contextStore)) {
+ DRIDestroyContextPriv(pDRIContextPriv);
+ return FALSE;
+ }
+ }
+
+ pDRIPriv->dummyCtxPriv = pDRIContextPriv;
+ return TRUE;
+}
+
+static void
+DRIDestroyDummyContext(ScreenPtr pScreen, Bool hasCtxPriv)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIContextPrivPtr pDRIContextPriv = pDRIPriv->dummyCtxPriv;
+ void *contextStore;
+
+ if (!pDRIContextPriv) return;
+ if (pDRIPriv->pDriverInfo->DestroyContext && hasCtxPriv) {
+ contextStore = DRIGetContextStore(pDRIContextPriv);
+ pDRIPriv->pDriverInfo->DestroyContext(pDRIContextPriv->pScreen,
+ pDRIContextPriv->hwContext,
+ (DRIContextType)(long)contextStore);
+ }
+
+ DRIDestroyContextPriv(pDRIPriv->dummyCtxPriv);
+ pDRIPriv->dummyCtxPriv = NULL;
+}
+
+Bool
+DRICreateContext(ScreenPtr pScreen, VisualPtr visual,
+ XID context, drm_context_t * pHWContext)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIContextPrivPtr pDRIContextPriv;
+ void *contextStore;
+
+ if (pDRIPriv->createDummyCtx && !pDRIPriv->dummyCtxPriv) {
+ if (!DRICreateDummyContext(pScreen, pDRIPriv->createDummyCtxPriv)) {
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Could not create dummy context\n");
+ return FALSE;
+ }
+ }
+
+ if (!(pDRIContextPriv = DRICreateContextPriv(pScreen, pHWContext, 0))) {
+ return FALSE;
+ }
+
+ contextStore = DRIGetContextStore(pDRIContextPriv);
+ if (pDRIPriv->pDriverInfo->CreateContext) {
+ if (!((*pDRIPriv->pDriverInfo->CreateContext)(pScreen, NULL,
+ *pHWContext, NULL,
+ (DRIContextType)(long)contextStore))) {
+ DRIDestroyContextPriv(pDRIContextPriv);
+ return FALSE;
+ }
+ }
+
+ /* track this in case the client dies before cleanup */
+ AddResource(context, DRIContextPrivResType, (pointer)pDRIContextPriv);
+
+ return TRUE;
+}
+
+Bool
+DRIDestroyContext(ScreenPtr pScreen, XID context)
+{
+ FreeResourceByType(context, DRIContextPrivResType, FALSE);
+
+ return TRUE;
+}
+
+/* DRIContextPrivDelete is called by the resource manager. */
+Bool
+DRIContextPrivDelete(pointer pResource, XID id)
+{
+ DRIContextPrivPtr pDRIContextPriv = (DRIContextPrivPtr)pResource;
+ DRIScreenPrivPtr pDRIPriv;
+ void *contextStore;
+
+ pDRIPriv = DRI_SCREEN_PRIV(pDRIContextPriv->pScreen);
+ if (pDRIPriv->pDriverInfo->DestroyContext) {
+ contextStore = DRIGetContextStore(pDRIContextPriv);
+ pDRIPriv->pDriverInfo->DestroyContext(pDRIContextPriv->pScreen,
+ pDRIContextPriv->hwContext,
+ (DRIContextType)(long)contextStore);
+ }
+ return DRIDestroyContextPriv(pDRIContextPriv);
+}
+
+
+/* This walks the drawable timestamp array and invalidates all of them
+ * in the case of transition from private to shared backbuffers. It's
+ * not necessary for correctness, because DRIClipNotify gets called in
+ * time to prevent any conflict, but the transition from
+ * shared->private is sometimes missed if we don't do this.
+ */
+static void
+DRIClipNotifyAllDrawables(ScreenPtr pScreen)
+{
+ int i;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ for( i=0; i < pDRIPriv->pDriverInfo->maxDrawableTableEntry; i++) {
+ pDRIPriv->pSAREA->drawableTable[i].stamp = DRIDrawableValidationStamp++;
+ }
+}
+
+
+static void
+DRITransitionToSharedBuffers(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
+ DRIClipNotifyAllDrawables( pScreen );
+
+ if (pDRIInfo->TransitionSingleToMulti3D)
+ pDRIInfo->TransitionSingleToMulti3D( pScreen );
+}
+
+
+static void
+DRITransitionToPrivateBuffers(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
+ DRIClipNotifyAllDrawables( pScreen );
+
+ if (pDRIInfo->TransitionMultiToSingle3D)
+ pDRIInfo->TransitionMultiToSingle3D( pScreen );
+}
+
+
+static void
+DRITransitionTo3d(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
+ DRIClipNotifyAllDrawables( pScreen );
+
+ if (pDRIInfo->TransitionTo3d)
+ pDRIInfo->TransitionTo3d( pScreen );
+}
+
+static void
+DRITransitionTo2d(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
+ DRIClipNotifyAllDrawables( pScreen );
+
+ if (pDRIInfo->TransitionTo2d)
+ pDRIInfo->TransitionTo2d( pScreen );
+}
+
+
+static int
+DRIDCNTreeTraversal(WindowPtr pWin, pointer data)
+{
+ DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+
+ if (pDRIDrawablePriv) {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (RegionNumRects(&pWin->clipList) > 0) {
+ WindowPtr *pDRIWindows = (WindowPtr*)data;
+ int i = 0;
+
+ while (pDRIWindows[i])
+ i++;
+
+ pDRIWindows[i] = pWin;
+
+ pDRIPriv->nrWalked++;
+ }
+
+ if (pDRIPriv->nrWindows == pDRIPriv->nrWalked)
+ return WT_STOPWALKING;
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static void
+DRIDriverClipNotify(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIPriv->pDriverInfo->ClipNotify) {
+ WindowPtr *pDRIWindows = calloc(sizeof(WindowPtr), pDRIPriv->nrWindows);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
+ if (pDRIPriv->nrWindows > 0) {
+ pDRIPriv->nrWalked = 0;
+ TraverseTree(pScreen->root, DRIDCNTreeTraversal,
+ (pointer)pDRIWindows);
+ }
+
+ pDRIInfo->ClipNotify(pScreen, pDRIWindows, pDRIPriv->nrWindows);
+
+ free(pDRIWindows);
+ }
+}
+
+static void
+DRIIncreaseNumberVisible(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ switch (++pDRIPriv->nrWindowsVisible) {
+ case 1:
+ DRITransitionTo3d( pScreen );
+ break;
+ case 2:
+ DRITransitionToSharedBuffers( pScreen );
+ break;
+ default:
+ break;
+ }
+
+ DRIDriverClipNotify(pScreen);
+}
+
+static void
+DRIDecreaseNumberVisible(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ switch (--pDRIPriv->nrWindowsVisible) {
+ case 0:
+ DRITransitionTo2d( pScreen );
+ break;
+ case 1:
+ DRITransitionToPrivateBuffers( pScreen );
+ break;
+ default:
+ break;
+ }
+
+ DRIDriverClipNotify(pScreen);
+}
+
+Bool
+DRICreateDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable,
+ drm_drawable_t * hHWDrawable)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+ WindowPtr pWin;
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ pWin = (WindowPtr)pDrawable;
+ if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
+ pDRIDrawablePriv->refCount++;
+
+ if (!pDRIDrawablePriv->hwDrawable) {
+ drmCreateDrawable(pDRIPriv->drmFD, &pDRIDrawablePriv->hwDrawable);
+ }
+ }
+ else {
+ /* allocate a DRI Window Private record */
+ if (!(pDRIDrawablePriv = malloc(sizeof(DRIDrawablePrivRec)))) {
+ return FALSE;
+ }
+
+ /* Only create a drm_drawable_t once */
+ if (drmCreateDrawable(pDRIPriv->drmFD,
+ &pDRIDrawablePriv->hwDrawable)) {
+ free(pDRIDrawablePriv);
+ return FALSE;
+ }
+
+ /* add it to the list of DRI drawables for this screen */
+ pDRIDrawablePriv->pScreen = pScreen;
+ pDRIDrawablePriv->refCount = 1;
+ pDRIDrawablePriv->drawableIndex = -1;
+ pDRIDrawablePriv->nrects = RegionNumRects(&pWin->clipList);
+
+ /* save private off of preallocated index */
+ dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey,
+ pDRIDrawablePriv);
+ pDRIPriv->nrWindows++;
+
+ if (pDRIDrawablePriv->nrects)
+ DRIIncreaseNumberVisible(pScreen);
+ }
+
+ /* track this in case the client dies */
+ AddResource(FakeClientID(client->index), DRIDrawablePrivResType,
+ (pointer)(intptr_t)pDrawable->id);
+
+ if (pDRIDrawablePriv->hwDrawable) {
+ drmUpdateDrawableInfo(pDRIPriv->drmFD,
+ pDRIDrawablePriv->hwDrawable,
+ DRM_DRAWABLE_CLIPRECTS,
+ RegionNumRects(&pWin->clipList),
+ RegionRects(&pWin->clipList));
+ *hHWDrawable = pDRIDrawablePriv->hwDrawable;
+ }
+ }
+ else if (pDrawable->type != DRAWABLE_PIXMAP) { /* PBuffer */
+ /* NOT_DONE */
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+DRIDrawablePrivDestroy(WindowPtr pWin)
+{
+ DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+ ScreenPtr pScreen;
+ DRIScreenPrivPtr pDRIPriv;
+
+ if (!pDRIDrawablePriv)
+ return;
+
+ pScreen = pWin->drawable.pScreen;
+ pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIDrawablePriv->drawableIndex != -1) {
+ /* bump stamp to force outstanding 3D requests to resync */
+ pDRIPriv->pSAREA->drawableTable[pDRIDrawablePriv->drawableIndex].stamp
+ = DRIDrawableValidationStamp++;
+
+ /* release drawable table entry */
+ pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
+ }
+
+ pDRIPriv->nrWindows--;
+
+ if (pDRIDrawablePriv->nrects)
+ DRIDecreaseNumberVisible(pScreen);
+
+ drmDestroyDrawable(pDRIPriv->drmFD, pDRIDrawablePriv->hwDrawable);
+
+ free(pDRIDrawablePriv);
+ dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
+}
+
+static Bool
+DRIDestroyDrawableCB(pointer value, XID id, pointer data)
+{
+ if (value == data) {
+ /* This calls back DRIDrawablePrivDelete which frees private area */
+ FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+Bool
+DRIDestroyDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable)
+{
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ LookupClientResourceComplex(client, DRIDrawablePrivResType,
+ DRIDestroyDrawableCB,
+ (pointer)(intptr_t)pDrawable->id);
+ }
+ else { /* pixmap (or for GLX 1.3, a PBuffer) */
+ /* NOT_DONE */
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+DRIDrawablePrivDelete(pointer pResource, XID id)
+{
+ WindowPtr pWin;
+ int rc;
+
+ /* For DRIDrawablePrivResType, the XID is the client's fake ID. The
+ * important XID is the value in pResource. */
+ id = (XID)(intptr_t)pResource;
+ rc = dixLookupWindow(&pWin, id, serverClient, DixGetAttrAccess);
+
+ if (rc == Success) {
+ DRIDrawablePrivPtr pDRIDrwPriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+
+ if (!pDRIDrwPriv)
+ return FALSE;
+
+ if (--pDRIDrwPriv->refCount == 0)
+ DRIDrawablePrivDestroy(pWin);
+
+ return TRUE;
+ }
+ else { /* pixmap (or for GLX 1.3, a PBuffer) */
+ /* NOT_DONE */
+ return FALSE;
+ }
+}
+
+Bool
+DRIGetDrawableInfo(ScreenPtr pScreen,
+ DrawablePtr pDrawable,
+ unsigned int* index,
+ unsigned int* stamp,
+ int* X,
+ int* Y,
+ int* W,
+ int* H,
+ int* numClipRects,
+ drm_clip_rect_t ** pClipRects,
+ int* backX,
+ int* backY,
+ int* numBackClipRects,
+ drm_clip_rect_t ** pBackClipRects)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv, pOldDrawPriv;
+ WindowPtr pWin, pOldWin;
+ int i;
+
+#if 0
+ printf("maxDrawableTableEntry = %d\n", pDRIPriv->pDriverInfo->maxDrawableTableEntry);
+#endif
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ pWin = (WindowPtr)pDrawable;
+ if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
+
+ /* Manage drawable table */
+ if (pDRIDrawablePriv->drawableIndex == -1) { /* load SAREA table */
+
+ /* Search table for empty entry */
+ i = 0;
+ while (i < pDRIPriv->pDriverInfo->maxDrawableTableEntry) {
+ if (!(pDRIPriv->DRIDrawables[i])) {
+ pDRIPriv->DRIDrawables[i] = pDrawable;
+ pDRIDrawablePriv->drawableIndex = i;
+ pDRIPriv->pSAREA->drawableTable[i].stamp =
+ DRIDrawableValidationStamp++;
+ break;
+ }
+ i++;
+ }
+
+ /* Search table for oldest entry */
+ if (i == pDRIPriv->pDriverInfo->maxDrawableTableEntry) {
+ unsigned int oldestStamp = ~0;
+ int oldestIndex = 0;
+ i = pDRIPriv->pDriverInfo->maxDrawableTableEntry;
+ while (i--) {
+ if (pDRIPriv->pSAREA->drawableTable[i].stamp <
+ oldestStamp) {
+ oldestIndex = i;
+ oldestStamp =
+ pDRIPriv->pSAREA->drawableTable[i].stamp;
+ }
+ }
+ pDRIDrawablePriv->drawableIndex = oldestIndex;
+
+ /* release oldest drawable table entry */
+ pOldWin = (WindowPtr)pDRIPriv->DRIDrawables[oldestIndex];
+ pOldDrawPriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pOldWin);
+ pOldDrawPriv->drawableIndex = -1;
+
+ /* claim drawable table entry */
+ pDRIPriv->DRIDrawables[oldestIndex] = pDrawable;
+
+ /* validate SAREA entry */
+ pDRIPriv->pSAREA->drawableTable[oldestIndex].stamp =
+ DRIDrawableValidationStamp++;
+
+ /* check for stamp wrap around */
+ if (oldestStamp > DRIDrawableValidationStamp) {
+
+ /* walk SAREA table and invalidate all drawables */
+ for( i=0;
+ i < pDRIPriv->pDriverInfo->maxDrawableTableEntry;
+ i++) {
+ pDRIPriv->pSAREA->drawableTable[i].stamp =
+ DRIDrawableValidationStamp++;
+ }
+ }
+ }
+
+ /* If the driver wants to be notified when the index is
+ * set for a drawable, let it know now.
+ */
+ if (pDRIPriv->pDriverInfo->SetDrawableIndex)
+ pDRIPriv->pDriverInfo->SetDrawableIndex(pWin,
+ pDRIDrawablePriv->drawableIndex);
+
+ /* reinit drawable ID if window is visible */
+ if ((pWin->viewable) &&
+ (pDRIPriv->pDriverInfo->bufferRequests != DRI_NO_WINDOWS))
+ {
+ (*pDRIPriv->pDriverInfo->InitBuffers)(pWin,
+ &pWin->clipList, pDRIDrawablePriv->drawableIndex);
+ }
+ }
+
+ *index = pDRIDrawablePriv->drawableIndex;
+ *stamp = pDRIPriv->pSAREA->drawableTable[*index].stamp;
+ *X = (int)(pWin->drawable.x);
+ *Y = (int)(pWin->drawable.y);
+ *W = (int)(pWin->drawable.width);
+ *H = (int)(pWin->drawable.height);
+ *numClipRects = RegionNumRects(&pWin->clipList);
+ *pClipRects = (drm_clip_rect_t *)RegionRects(&pWin->clipList);
+
+ if (!*numClipRects && pDRIPriv->fullscreen) {
+ /* use fake full-screen clip rect */
+ pDRIPriv->fullscreen_rect.x1 = *X;
+ pDRIPriv->fullscreen_rect.y1 = *Y;
+ pDRIPriv->fullscreen_rect.x2 = *X + *W;
+ pDRIPriv->fullscreen_rect.y2 = *Y + *H;
+
+ *numClipRects = 1;
+ *pClipRects = &pDRIPriv->fullscreen_rect;
+ }
+
+ *backX = *X;
+ *backY = *Y;
+
+ if (pDRIPriv->nrWindowsVisible == 1 && *numClipRects) {
+ /* Use a single cliprect. */
+
+ int x0 = *X;
+ int y0 = *Y;
+ int x1 = x0 + *W;
+ int y1 = y0 + *H;
+
+ if (x0 < 0) x0 = 0;
+ if (y0 < 0) y0 = 0;
+ if (x1 > pScreen->width) x1 = pScreen->width;
+ if (y1 > pScreen->height) y1 = pScreen->height;
+
+ if (y0 >= y1 || x0 >= x1) {
+ *numBackClipRects = 0;
+ *pBackClipRects = NULL;
+ } else {
+ pDRIPriv->private_buffer_rect.x1 = x0;
+ pDRIPriv->private_buffer_rect.y1 = y0;
+ pDRIPriv->private_buffer_rect.x2 = x1;
+ pDRIPriv->private_buffer_rect.y2 = y1;
+
+ *numBackClipRects = 1;
+ *pBackClipRects = &(pDRIPriv->private_buffer_rect);
+ }
+ } else {
+ /* Use the frontbuffer cliprects for back buffers. */
+ *numBackClipRects = 0;
+ *pBackClipRects = 0;
+ }
+ }
+ else {
+ /* Not a DRIDrawable */
+ return FALSE;
+ }
+ }
+ else { /* pixmap (or for GLX 1.3, a PBuffer) */
+ /* NOT_DONE */
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+DRIGetDeviceInfo(ScreenPtr pScreen,
+ drm_handle_t * hFrameBuffer,
+ int* fbOrigin,
+ int* fbSize,
+ int* fbStride,
+ int* devPrivateSize,
+ void** pDevPrivate)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ *hFrameBuffer = pDRIPriv->pDriverInfo->hFrameBuffer;
+ *fbOrigin = 0;
+ *fbSize = pDRIPriv->pDriverInfo->frameBufferSize;
+ *fbStride = pDRIPriv->pDriverInfo->frameBufferStride;
+ *devPrivateSize = pDRIPriv->pDriverInfo->devPrivateSize;
+ *pDevPrivate = pDRIPriv->pDriverInfo->devPrivate;
+
+ return TRUE;
+}
+
+DRIInfoPtr
+DRICreateInfoRec(void)
+{
+ DRIInfoPtr inforec = (DRIInfoPtr)calloc(1, sizeof(DRIInfoRec));
+ if (!inforec) return NULL;
+
+ /* Initialize defaults */
+ inforec->busIdString = NULL;
+
+ /* Wrapped function defaults */
+ inforec->wrap.WakeupHandler = DRIDoWakeupHandler;
+ inforec->wrap.BlockHandler = DRIDoBlockHandler;
+ inforec->wrap.WindowExposures = DRIWindowExposures;
+ inforec->wrap.CopyWindow = DRICopyWindow;
+ inforec->wrap.ValidateTree = DRIValidateTree;
+ inforec->wrap.PostValidateTree = DRIPostValidateTree;
+ inforec->wrap.ClipNotify = DRIClipNotify;
+ inforec->wrap.AdjustFrame = DRIAdjustFrame;
+
+ inforec->TransitionTo2d = 0;
+ inforec->TransitionTo3d = 0;
+ inforec->SetDrawableIndex = 0;
+
+ return inforec;
+}
+
+void
+DRIDestroyInfoRec(DRIInfoPtr DRIInfo)
+{
+ free(DRIInfo->busIdString);
+ free((char*)DRIInfo);
+}
+
+
+void
+DRIWakeupHandler(pointer wakeupData, int result, pointer pReadmask)
+{
+ int i;
+
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIPriv &&
+ pDRIPriv->pDriverInfo->wrap.WakeupHandler)
+ (*pDRIPriv->pDriverInfo->wrap.WakeupHandler)(i, wakeupData,
+ result, pReadmask);
+ }
+}
+
+void
+DRIBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
+{
+ int i;
+
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIPriv &&
+ pDRIPriv->pDriverInfo->wrap.BlockHandler)
+ (*pDRIPriv->pDriverInfo->wrap.BlockHandler)(i, blockData,
+ pTimeout, pReadmask);
+ }
+}
+
+void
+DRIDoWakeupHandler(int screenNum, pointer wakeupData,
+ unsigned long result, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ DRILock(pScreen, 0);
+ if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
+ /* hide X context by swapping 2D component here */
+ (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
+ DRI_3D_SYNC,
+ DRI_2D_CONTEXT,
+ pDRIPriv->partial3DContextStore,
+ DRI_2D_CONTEXT,
+ pDRIPriv->hiddenContextStore);
+ }
+}
+
+void
+DRIDoBlockHandler(int screenNum, pointer blockData,
+ pointer pTimeout, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
+ /* hide X context by swapping 2D component here */
+ (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
+ DRI_2D_SYNC,
+ DRI_NO_CONTEXT,
+ NULL,
+ DRI_2D_CONTEXT,
+ pDRIPriv->partial3DContextStore);
+ }
+
+ if (pDRIPriv->windowsTouched)
+ DRM_SPINUNLOCK(&pDRIPriv->pSAREA->drawable_lock, 1);
+ pDRIPriv->windowsTouched = FALSE;
+
+ DRIUnlock(pScreen);
+}
+
+void
+DRISwapContext(int drmFD, void *oldctx, void *newctx)
+{
+ DRIContextPrivPtr oldContext = (DRIContextPrivPtr)oldctx;
+ DRIContextPrivPtr newContext = (DRIContextPrivPtr)newctx;
+ ScreenPtr pScreen = newContext->pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ void* oldContextStore = NULL;
+ DRIContextType oldContextType;
+ void* newContextStore = NULL;
+ DRIContextType newContextType;
+ DRISyncType syncType;
+#ifdef DEBUG
+ static int count = 0;
+
+ if (!newContext) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI] Context Switch Error: oldContext=%x, newContext=%x\n",
+ oldContext, newContext);
+ return;
+ }
+
+ /* usefull for debugging, just print out after n context switches */
+ if (!count || !(count % 1)) {
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[DRI] Context switch %5d from %p/0x%08x (%d)\n",
+ count,
+ oldContext,
+ oldContext ? oldContext->flags : 0,
+ oldContext ? oldContext->hwContext : -1);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[DRI] Context switch %5d to %p/0x%08x (%d)\n",
+ count,
+ newContext,
+ newContext ? newContext->flags : 0,
+ newContext ? newContext->hwContext : -1);
+ }
+ ++count;
+#endif
+
+ if (!pDRIPriv->pDriverInfo->SwapContext) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI] DDX driver missing context swap call back\n");
+ return;
+ }
+
+ if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
+
+ /* only 3D contexts are swapped in this case */
+ if (oldContext) {
+ oldContextStore = DRIGetContextStore(oldContext);
+ oldContext->valid3D = TRUE;
+ oldContextType = DRI_3D_CONTEXT;
+ } else {
+ oldContextType = DRI_NO_CONTEXT;
+ }
+ newContextStore = DRIGetContextStore(newContext);
+ if ((newContext->valid3D) &&
+ (newContext->hwContext != pDRIPriv->myContext)) {
+ newContextType = DRI_3D_CONTEXT;
+ }
+ else {
+ newContextType = DRI_2D_CONTEXT;
+ }
+ syncType = DRI_3D_SYNC;
+ }
+ else /* default: driverSwapMethod == DRI_SERVER_SWAP */ {
+
+ /* optimize 2D context swaps */
+
+ if (newContext->flags & DRI_CONTEXT_2DONLY) {
+ /* go from 3D context to 2D context and only save 2D
+ * subset of 3D state
+ */
+ oldContextStore = DRIGetContextStore(oldContext);
+ oldContextType = DRI_2D_CONTEXT;
+ newContextStore = DRIGetContextStore(newContext);
+ newContextType = DRI_2D_CONTEXT;
+ syncType = DRI_3D_SYNC;
+ pDRIPriv->lastPartial3DContext = oldContext;
+ }
+ else if (oldContext->flags & DRI_CONTEXT_2DONLY) {
+ if (pDRIPriv->lastPartial3DContext == newContext) {
+ /* go from 2D context back to previous 3D context and
+ * only restore 2D subset of previous 3D state
+ */
+ oldContextStore = DRIGetContextStore(oldContext);
+ oldContextType = DRI_2D_CONTEXT;
+ newContextStore = DRIGetContextStore(newContext);
+ newContextType = DRI_2D_CONTEXT;
+ syncType = DRI_2D_SYNC;
+ }
+ else {
+ /* go from 2D context to a different 3D context */
+
+ /* call DDX driver to do partial restore */
+ oldContextStore = DRIGetContextStore(oldContext);
+ newContextStore =
+ DRIGetContextStore(pDRIPriv->lastPartial3DContext);
+ (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
+ DRI_2D_SYNC,
+ DRI_2D_CONTEXT,
+ oldContextStore,
+ DRI_2D_CONTEXT,
+ newContextStore);
+
+ /* now setup for a complete 3D swap */
+ oldContextStore = newContextStore;
+ oldContext->valid3D = TRUE;
+ oldContextType = DRI_3D_CONTEXT;
+ newContextStore = DRIGetContextStore(newContext);
+ if ((newContext->valid3D) &&
+ (newContext->hwContext != pDRIPriv->myContext)) {
+ newContextType = DRI_3D_CONTEXT;
+ }
+ else {
+ newContextType = DRI_2D_CONTEXT;
+ }
+ syncType = DRI_NO_SYNC;
+ }
+ }
+ else {
+ /* now setup for a complete 3D swap */
+ oldContextStore = newContextStore;
+ oldContext->valid3D = TRUE;
+ oldContextType = DRI_3D_CONTEXT;
+ newContextStore = DRIGetContextStore(newContext);
+ if ((newContext->valid3D) &&
+ (newContext->hwContext != pDRIPriv->myContext)) {
+ newContextType = DRI_3D_CONTEXT;
+ }
+ else {
+ newContextType = DRI_2D_CONTEXT;
+ }
+ syncType = DRI_3D_SYNC;
+ }
+ }
+
+ /* call DDX driver to perform the swap */
+ (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
+ syncType,
+ oldContextType,
+ oldContextStore,
+ newContextType,
+ newContextStore);
+}
+
+void*
+DRIGetContextStore(DRIContextPrivPtr context)
+{
+ return((void *)context->pContextStore);
+}
+
+void
+DRIWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr bsreg)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+
+ if(pDRIDrawablePriv) {
+ (*pDRIPriv->pDriverInfo->InitBuffers)(pWin, prgn,
+ pDRIDrawablePriv->drawableIndex);
+ }
+
+ /* call lower wrapped functions */
+ if (pDRIPriv && pDRIPriv->wrap.WindowExposures) {
+
+ /* unwrap */
+ pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
+
+ /* call lower layers */
+ (*pScreen->WindowExposures)(pWin, prgn, bsreg);
+
+ /* rewrap */
+ pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
+ pScreen->WindowExposures = DRIWindowExposures;
+ }
+}
+
+
+static int
+DRITreeTraversal(WindowPtr pWin, pointer data)
+{
+ DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+
+ if(pDRIDrawablePriv) {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if(RegionNumRects(&(pWin->clipList)) > 0) {
+ RegionPtr reg = (RegionPtr)data;
+
+ RegionUnion(reg, reg, &(pWin->clipList));
+ pDRIPriv->nrWalked++;
+ }
+
+ if(pDRIPriv->nrWindows == pDRIPriv->nrWalked)
+ return WT_STOPWALKING;
+ }
+ return WT_WALKCHILDREN;
+}
+
+Bool
+DRIDestroyWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ Bool retval = TRUE;
+
+ DRIDrawablePrivDestroy(pWin);
+
+ /* call lower wrapped functions */
+ if(pDRIPriv->DestroyWindow) {
+ /* unwrap */
+ pScreen->DestroyWindow = pDRIPriv->DestroyWindow;
+
+ /* call lower layers */
+ retval = (*pScreen->DestroyWindow)(pWin);
+
+ /* rewrap */
+ pDRIPriv->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = DRIDestroyWindow;
+ }
+
+ return retval;
+}
+
+void
+DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if(!pDRIPriv) return;
+
+ if(pDRIPriv->nrWindowsVisible > 0) {
+ RegionRec reg;
+
+ RegionNull(&reg);
+ pDRIPriv->nrWalked = 0;
+ TraverseTree(pWin, DRITreeTraversal, (pointer)(&reg));
+
+ if(RegionNotEmpty(&reg)) {
+ RegionTranslate(&reg, ptOldOrg.x - pWin->drawable.x,
+ ptOldOrg.y - pWin->drawable.y);
+ RegionIntersect(&reg, &reg, prgnSrc);
+
+ /* The MoveBuffers interface is not ideal */
+ (*pDRIPriv->pDriverInfo->MoveBuffers)(pWin, ptOldOrg, &reg,
+ pDRIPriv->pDriverInfo->ddxDrawableTableEntry);
+ }
+
+ RegionUninit(&reg);
+ }
+
+ /* call lower wrapped functions */
+ if(pDRIPriv->wrap.CopyWindow) {
+ /* unwrap */
+ pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
+
+ /* call lower layers */
+ (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
+
+ /* rewrap */
+ pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
+ pScreen->CopyWindow = DRICopyWindow;
+ }
+}
+
+static void
+DRIGetSecs(long *secs, long *usecs)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+
+ *secs = tv.tv_sec;
+ *usecs = tv.tv_usec;
+}
+
+static unsigned long
+DRIComputeMilliSeconds(unsigned long s_secs, unsigned long s_usecs,
+ unsigned long f_secs, unsigned long f_usecs)
+{
+ if (f_usecs < s_usecs) {
+ --f_secs;
+ f_usecs += 1000000;
+ }
+ return (f_secs - s_secs) * 1000 + (f_usecs - s_usecs) / 1000;
+}
+
+static void
+DRISpinLockTimeout(drmLock *lock, int val, unsigned long timeout /* in mS */)
+{
+ int count = 10000;
+#if !defined(__alpha__) && !defined(__powerpc__)
+ char ret;
+#else
+ int ret;
+#endif
+ long s_secs, s_usecs;
+ long f_secs, f_usecs;
+ long msecs;
+ long prev = 0;
+
+ DRIGetSecs(&s_secs, &s_usecs);
+
+ do {
+ DRM_SPINLOCK_COUNT(lock, val, count, ret);
+ if (!ret) return; /* Got lock */
+ DRIGetSecs(&f_secs, &f_usecs);
+ msecs = DRIComputeMilliSeconds(s_secs, s_usecs, f_secs, f_usecs);
+ if (msecs - prev < 250) count *= 2; /* Not more than 0.5S */
+ } while (msecs < timeout);
+
+ /* Didn't get lock, so take it. The worst
+ that can happen is that there is some
+ garbage written to the wrong part of the
+ framebuffer that a refresh will repair.
+ That's undesirable, but better than
+ locking the server. This should be a
+ very rare event. */
+ DRM_SPINLOCK_TAKE(lock, val);
+}
+
+static void
+DRILockTree(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if(!pDRIPriv) return;
+
+ /* Restore the last known 3D context if the X context is hidden */
+ if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
+ (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
+ DRI_2D_SYNC,
+ DRI_NO_CONTEXT,
+ NULL,
+ DRI_2D_CONTEXT,
+ pDRIPriv->partial3DContextStore);
+ }
+
+ /* Call kernel to release lock */
+ DRIUnlock(pScreen);
+
+ /* Grab drawable spin lock: a time out between 10 and 30 seconds is
+ appropriate, since this should never time out except in the case of
+ client death while the lock is being held. The timeout must be
+ greater than any reasonable rendering time. */
+ DRISpinLockTimeout(&pDRIPriv->pSAREA->drawable_lock, 1, 10000); /*10 secs*/
+
+ /* Call kernel flush outstanding buffers and relock */
+ DRILock(pScreen, DRM_LOCK_QUIESCENT|DRM_LOCK_FLUSH_ALL);
+
+ /* Switch back to our 2D context if the X context is hidden */
+ if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
+ /* hide X context by swapping 2D component here */
+ (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
+ DRI_3D_SYNC,
+ DRI_2D_CONTEXT,
+ pDRIPriv->partial3DContextStore,
+ DRI_2D_CONTEXT,
+ pDRIPriv->hiddenContextStore);
+ }
+}
+
+int
+DRIValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
+{
+ ScreenPtr pScreen = pParent->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ int returnValue = 1; /* always return 1, not checked by dix/window.c */
+
+ if(!pDRIPriv) return returnValue;
+
+ /* call lower wrapped functions */
+ if(pDRIPriv->wrap.ValidateTree) {
+ /* unwrap */
+ pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree;
+
+ /* call lower layers */
+ returnValue = (*pScreen->ValidateTree)(pParent, pChild, kind);
+
+ /* rewrap */
+ pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
+ pScreen->ValidateTree = DRIValidateTree;
+ }
+
+ return returnValue;
+}
+
+void
+DRIPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
+{
+ ScreenPtr pScreen;
+ DRIScreenPrivPtr pDRIPriv;
+
+ if (pParent) {
+ pScreen = pParent->drawable.pScreen;
+ } else {
+ pScreen = pChild->drawable.pScreen;
+ }
+ if(!(pDRIPriv = DRI_SCREEN_PRIV(pScreen))) return;
+
+ if (pDRIPriv->wrap.PostValidateTree) {
+ /* unwrap */
+ pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree;
+
+ /* call lower layers */
+ (*pScreen->PostValidateTree)(pParent, pChild, kind);
+
+ /* rewrap */
+ pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
+ pScreen->PostValidateTree = DRIPostValidateTree;
+ }
+}
+
+void
+DRIClipNotify(WindowPtr pWin, int dx, int dy)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+
+ if(!pDRIPriv) return;
+
+ if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
+ int nrects = RegionNumRects(&pWin->clipList);
+
+ if(!pDRIPriv->windowsTouched) {
+ DRILockTree(pScreen);
+ pDRIPriv->windowsTouched = TRUE;
+ }
+
+ if (nrects && !pDRIDrawablePriv->nrects)
+ DRIIncreaseNumberVisible(pScreen);
+ else if (!nrects && pDRIDrawablePriv->nrects)
+ DRIDecreaseNumberVisible(pScreen);
+ else
+ DRIDriverClipNotify(pScreen);
+
+ pDRIDrawablePriv->nrects = nrects;
+
+ pDRIPriv->pSAREA->drawableTable[pDRIDrawablePriv->drawableIndex].stamp
+ = DRIDrawableValidationStamp++;
+
+ drmUpdateDrawableInfo(pDRIPriv->drmFD, pDRIDrawablePriv->hwDrawable,
+ DRM_DRAWABLE_CLIPRECTS,
+ nrects, RegionRects(&pWin->clipList));
+ }
+
+ /* call lower wrapped functions */
+ if(pDRIPriv->wrap.ClipNotify) {
+
+ /* unwrap */
+ pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
+
+ /* call lower layers */
+ (*pScreen->ClipNotify)(pWin, dx, dy);
+
+ /* rewrap */
+ pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
+ pScreen->ClipNotify = DRIClipNotify;
+ }
+}
+
+CARD32
+DRIGetDrawableIndex(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+ CARD32 index;
+
+ if (pDRIDrawablePriv) {
+ index = pDRIDrawablePriv->drawableIndex;
+ }
+ else {
+ index = pDRIPriv->pDriverInfo->ddxDrawableTableEntry;
+ }
+
+ return index;
+}
+
+unsigned int
+DRIGetDrawableStamp(ScreenPtr pScreen, CARD32 drawable_index)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ return pDRIPriv->pSAREA->drawableTable[drawable_index].stamp;
+}
+
+
+void
+DRIPrintDrawableLock(ScreenPtr pScreen, char *msg)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ ErrorF("%s: %d\n", msg, pDRIPriv->pSAREA->drawable_lock.lock);
+}
+
+void
+DRILock(ScreenPtr pScreen, int flags)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
+
+ if (!*pDRIPriv->pLockRefCount) {
+ DRM_LOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext, flags);
+ *pDRIPriv->pLockingContext = pDRIPriv->myContext;
+ } else if (*pDRIPriv->pLockingContext != pDRIPriv->myContext) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI] Locking deadlock.\n"
+ "\tAlready locked with context %d,\n"
+ "\ttrying to lock with context %d.\n",
+ pDRIPriv->pLockingContext,
+ pDRIPriv->myContext);
+ }
+ (*pDRIPriv->pLockRefCount)++;
+}
+
+void
+DRIUnlock(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
+
+ if (*pDRIPriv->pLockRefCount > 0) {
+ if (pDRIPriv->myContext != *pDRIPriv->pLockingContext) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI] Unlocking inconsistency:\n"
+ "\tContext %d trying to unlock lock held by context %d\n",
+ pDRIPriv->pLockingContext,
+ pDRIPriv->myContext);
+ }
+ (*pDRIPriv->pLockRefCount)--;
+ } else {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "DRIUnlock called when not locked.\n");
+ return;
+ }
+ if (! *pDRIPriv->pLockRefCount)
+ DRM_UNLOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext);
+}
+
+void *
+DRIGetSAREAPrivate(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ if (!pDRIPriv) return 0;
+
+ return (void *)(((char*)pDRIPriv->pSAREA)+sizeof(XF86DRISAREARec));
+}
+
+drm_context_t
+DRIGetContext(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ if (!pDRIPriv) return 0;
+
+ return pDRIPriv->myContext;
+}
+
+void
+DRIGetTexOffsetFuncs(ScreenPtr pScreen,
+ DRITexOffsetStartProcPtr *texOffsetStartFunc,
+ DRITexOffsetFinishProcPtr *texOffsetFinishFunc)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (!pDRIPriv) return;
+
+ *texOffsetStartFunc = pDRIPriv->pDriverInfo->texOffsetStart;
+ *texOffsetFinishFunc = pDRIPriv->pDriverInfo->texOffsetFinish;
+}
+
+/* This lets get at the unwrapped functions so that they can correctly
+ * call the lowerlevel functions, and choose whether they will be
+ * called at every level of recursion (eg in validatetree).
+ */
+DRIWrappedFuncsRec *
+DRIGetWrappedFuncs(ScreenPtr pScreen)
+{
+ return &(DRI_SCREEN_PRIV(pScreen)->wrap);
+}
+
+/* note that this returns the library version, not the protocol version */
+void
+DRIQueryVersion(int *majorVersion,
+ int *minorVersion,
+ int *patchVersion)
+{
+ *majorVersion = DRIINFO_MAJOR_VERSION;
+ *minorVersion = DRIINFO_MINOR_VERSION;
+ *patchVersion = DRIINFO_PATCH_VERSION;
+}
+
+static void
+_DRIAdjustFrame(ScrnInfoPtr pScrn, DRIScreenPrivPtr pDRIPriv, int x, int y)
+{
+ pDRIPriv->pSAREA->frame.x = x;
+ pDRIPriv->pSAREA->frame.y = y;
+ pDRIPriv->pSAREA->frame.width = pScrn->frameX1 - x + 1;
+ pDRIPriv->pSAREA->frame.height = pScrn->frameY1 - y + 1;
+}
+
+void
+DRIAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[scrnIndex];
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ int px, py;
+
+ if (!pDRIPriv || !pDRIPriv->pSAREA) {
+ DRIDrvMsg(scrnIndex, X_ERROR, "[DRI] No SAREA (%p %p)\n",
+ pDRIPriv, pDRIPriv ? pDRIPriv->pSAREA : NULL);
+ return;
+ }
+
+ if (pDRIPriv->fullscreen) {
+ /* Fix up frame */
+ pScrn->frameX0 = pDRIPriv->pSAREA->frame.x;
+ pScrn->frameY0 = pDRIPriv->pSAREA->frame.y;
+ pScrn->frameX1 = pScrn->frameX0 + pDRIPriv->pSAREA->frame.width - 1;
+ pScrn->frameY1 = pScrn->frameY0 + pDRIPriv->pSAREA->frame.height - 1;
+
+ /* Fix up cursor */
+ miPointerGetPosition(inputInfo.pointer, &px, &py);
+ if (px < pScrn->frameX0) px = pScrn->frameX0;
+ if (px > pScrn->frameX1) px = pScrn->frameX1;
+ if (py < pScrn->frameY0) py = pScrn->frameY0;
+ if (py > pScrn->frameY1) py = pScrn->frameY1;
+ pScreen->SetCursorPosition(inputInfo.pointer, pScreen, px, py, TRUE);
+ return;
+ }
+
+ if (pDRIPriv->wrap.AdjustFrame) {
+ /* unwrap */
+ pScrn->AdjustFrame = pDRIPriv->wrap.AdjustFrame;
+ /* call lower layers */
+ (*pScrn->AdjustFrame)(scrnIndex, x, y, flags);
+ /* rewrap */
+ pDRIPriv->wrap.AdjustFrame = pScrn->AdjustFrame;
+ pScrn->AdjustFrame = DRIAdjustFrame;
+ }
+
+ _DRIAdjustFrame(pScrn, pDRIPriv, x, y);
+}
+
+/*
+ * DRIMoveBuffersHelper swaps the regions rects in place leaving you
+ * a region with the rects in the order that you need to blit them,
+ * but it is possibly (likely) an invalid region afterwards. If you
+ * need to use the region again for anything you have to call
+ * REGION_VALIDATE on it, or better yet, save a copy first.
+ */
+
+void
+DRIMoveBuffersHelper(
+ ScreenPtr pScreen,
+ int dx,
+ int dy,
+ int *xdir,
+ int *ydir,
+ RegionPtr reg
+)
+{
+ BoxPtr extents, pbox, firstBox, lastBox;
+ BoxRec tmpBox;
+ int y, nbox;
+
+ extents = RegionExtents(reg);
+ nbox = RegionNumRects(reg);
+ pbox = RegionRects(reg);
+
+ if((dy > 0) && (dy < (extents->y2 - extents->y1))) {
+ *ydir = -1;
+ if(nbox > 1) {
+ firstBox = pbox;
+ lastBox = pbox + nbox - 1;
+ while((unsigned long)firstBox < (unsigned long)lastBox) {
+ tmpBox = *firstBox;
+ *firstBox = *lastBox;
+ *lastBox = tmpBox;
+ firstBox++;
+ lastBox--;
+ }
+ }
+ } else *ydir = 1;
+
+ if((dx > 0) && (dx < (extents->x2 - extents->x1))) {
+ *xdir = -1;
+ if(nbox > 1) {
+ firstBox = lastBox = pbox;
+ y = pbox->y1;
+ while(--nbox) {
+ pbox++;
+ if(pbox->y1 == y) lastBox++;
+ else {
+ while((unsigned long)firstBox < (unsigned long)lastBox) {
+ tmpBox = *firstBox;
+ *firstBox = *lastBox;
+ *lastBox = tmpBox;
+ firstBox++;
+ lastBox--;
+ }
+
+ firstBox = lastBox = pbox;
+ y = pbox->y1;
+ }
+ }
+ while((unsigned long)firstBox < (unsigned long)lastBox) {
+ tmpBox = *firstBox;
+ *firstBox = *lastBox;
+ *lastBox = tmpBox;
+ firstBox++;
+ lastBox--;
+ }
+ }
+ } else *xdir = 1;
+
+}
+
+char *
+DRICreatePCIBusID(const struct pci_device * dev)
+{
+ char *busID;
+
+ if (asprintf(&busID, "pci:%04x:%02x:%02x.%d",
+ dev->domain, dev->bus, dev->dev, dev->func) == -1)
+ return NULL;
+
+ return busID;
+}
+
+static void drmSIGIOHandler(int interrupt, void *closure)
+{
+ unsigned long key;
+ void *value;
+ ssize_t count;
+ drm_ctx_t ctx;
+ typedef void (*_drmCallback)(int, void *, void *);
+ char buf[256];
+ drm_context_t old;
+ drm_context_t new;
+ void *oldctx;
+ void *newctx;
+ char *pt;
+ drmHashEntry *entry;
+ void *hash_table;
+
+ hash_table = drmGetHashTable();
+
+ if (!hash_table) return;
+ if (drmHashFirst(hash_table, &key, &value)) {
+ entry = value;
+ do {
+#if 0
+ fprintf(stderr, "Trying %d\n", entry->fd);
+#endif
+ if ((count = read(entry->fd, buf, sizeof(buf) - 1)) > 0) {
+ buf[count] = '\0';
+#if 0
+ fprintf(stderr, "Got %s\n", buf);
+#endif
+
+ for (pt = buf; *pt != ' '; ++pt); /* Find first space */
+ ++pt;
+ old = strtol(pt, &pt, 0);
+ new = strtol(pt, NULL, 0);
+ oldctx = drmGetContextTag(entry->fd, old);
+ newctx = drmGetContextTag(entry->fd, new);
+#if 0
+ fprintf(stderr, "%d %d %p %p\n", old, new, oldctx, newctx);
+#endif
+ ((_drmCallback)entry->f)(entry->fd, oldctx, newctx);
+ ctx.handle = new;
+ ioctl(entry->fd, DRM_IOCTL_NEW_CTX, &ctx);
+ }
+ } while (drmHashNext(hash_table, &key, &value));
+ }
+}
+
+
+int drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *))
+{
+ drmHashEntry *entry;
+
+ entry = drmGetEntry(fd);
+ entry->f = f;
+
+ return xf86InstallSIGIOHandler(fd, drmSIGIOHandler, 0);
+}
+
+int drmRemoveSIGIOHandler(int fd)
+{
+ drmHashEntry *entry = drmGetEntry(fd);
+
+ entry->f = NULL;
+
+ return xf86RemoveSIGIOHandler(fd);
+}
diff --git a/xorg-server/hw/xfree86/dri/xf86dri.c b/xorg-server/hw/xfree86/dri/xf86dri.c
index e02644a30..ba9d5a1e4 100644
--- a/xorg-server/hw/xfree86/dri/xf86dri.c
+++ b/xorg-server/hw/xfree86/dri/xf86dri.c
@@ -1,662 +1,662 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, Inc.
-All Rights Reserved.
-
-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, sub license, 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 NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Kevin E. Martin <martin@valinux.com>
- * Jens Owen <jens@tungstengraphics.com>
- * Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "xf86.h"
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "scrnintstr.h"
-#include "servermd.h"
-#define _XF86DRI_SERVER_
-#include <X11/dri/xf86driproto.h>
-#include "swaprep.h"
-#include "xf86str.h"
-#include "dri.h"
-#include "sarea.h"
-#include "dristruct.h"
-#include "xf86drm.h"
-#include "protocol-versions.h"
-
-static int DRIErrorBase;
-
-
-
-static void XF86DRIResetProc(ExtensionEntry* extEntry);
-
-static unsigned char DRIReqCode = 0;
-
-extern void XFree86DRIExtensionInit(void);
-
-/*ARGSUSED*/
-static void
-XF86DRIResetProc (
- ExtensionEntry* extEntry
-)
-{
- DRIReset();
-}
-
-static int
-ProcXF86DRIQueryVersion(
- register ClientPtr client
-)
-{
- xXF86DRIQueryVersionReply rep;
- register int n;
-
- REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = SERVER_XF86DRI_MAJOR_VERSION;
- rep.minorVersion = SERVER_XF86DRI_MINOR_VERSION;
- rep.patchVersion = SERVER_XF86DRI_PATCH_VERSION;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.majorVersion, n);
- swaps(&rep.minorVersion, n);
- swapl(&rep.patchVersion, n);
- }
- WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXF86DRIQueryDirectRenderingCapable(
- register ClientPtr client
-)
-{
- xXF86DRIQueryDirectRenderingCapableReply rep;
- Bool isCapable;
- register int n;
-
- REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
- REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if (!DRIQueryDirectRenderingCapable( screenInfo.screens[stuff->screen],
- &isCapable)) {
- return BadValue;
- }
- rep.isCapable = isCapable;
-
- if (!LocalClient(client) || client->swapped)
- rep.isCapable = 0;
-
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- }
-
- WriteToClient(client,
- sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXF86DRIOpenConnection(
- register ClientPtr client
-)
-{
- xXF86DRIOpenConnectionReply rep;
- drm_handle_t hSAREA;
- char* busIdString;
-
- REQUEST(xXF86DRIOpenConnectionReq);
- REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- if (!DRIOpenConnection( screenInfo.screens[stuff->screen],
- &hSAREA,
- &busIdString)) {
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.busIdStringLength = 0;
- if (busIdString)
- rep.busIdStringLength = strlen(busIdString);
- rep.length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
- pad_to_int32(rep.busIdStringLength));
-
- rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff);
-#if defined(LONG64) && !defined(__linux__)
- rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
-#else
- rep.hSAREAHigh = 0;
-#endif
-
- WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
- if (rep.busIdStringLength)
- WriteToClient(client, rep.busIdStringLength, busIdString);
- return Success;
-}
-
-static int
-ProcXF86DRIAuthConnection(
- register ClientPtr client
-)
-{
- xXF86DRIAuthConnectionReply rep;
-
- REQUEST(xXF86DRIAuthConnectionReq);
- REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.authenticated = 1;
-
- if (!DRIAuthConnection( screenInfo.screens[stuff->screen], stuff->magic)) {
- ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic);
- rep.authenticated = 0;
- }
- WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXF86DRICloseConnection(
- register ClientPtr client
-)
-{
- REQUEST(xXF86DRICloseConnectionReq);
- REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- DRICloseConnection( screenInfo.screens[stuff->screen]);
-
- return Success;
-}
-
-static int
-ProcXF86DRIGetClientDriverName(
- register ClientPtr client
-)
-{
- xXF86DRIGetClientDriverNameReply rep;
- char* clientDriverName;
-
- REQUEST(xXF86DRIGetClientDriverNameReq);
- REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- DRIGetClientDriverName( screenInfo.screens[stuff->screen],
- (int *)&rep.ddxDriverMajorVersion,
- (int *)&rep.ddxDriverMinorVersion,
- (int *)&rep.ddxDriverPatchVersion,
- &clientDriverName);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.clientDriverNameLength = 0;
- if (clientDriverName)
- rep.clientDriverNameLength = strlen(clientDriverName);
- rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) -
- SIZEOF(xGenericReply) +
- pad_to_int32(rep.clientDriverNameLength));
-
- WriteToClient(client,
- sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
- if (rep.clientDriverNameLength)
- WriteToClient(client,
- rep.clientDriverNameLength,
- clientDriverName);
- return Success;
-}
-
-static int
-ProcXF86DRICreateContext(
- register ClientPtr client
-)
-{
- xXF86DRICreateContextReply rep;
- ScreenPtr pScreen;
-
- REQUEST(xXF86DRICreateContextReq);
- REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- pScreen = screenInfo.screens[stuff->screen];
-
- if (!DRICreateContext( pScreen,
- NULL,
- stuff->context,
- (drm_context_t *)&rep.hHWContext)) {
- return BadValue;
- }
-
- WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXF86DRIDestroyContext(
- register ClientPtr client
-)
-{
- REQUEST(xXF86DRIDestroyContextReq);
- REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
- stuff->context)) {
- return BadValue;
- }
-
- return Success;
-}
-
-static int
-ProcXF86DRICreateDrawable(
- ClientPtr client
-)
-{
- xXF86DRICreateDrawableReply rep;
- DrawablePtr pDrawable;
- int rc;
-
- REQUEST(xXF86DRICreateDrawableReq);
- REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if (!DRICreateDrawable(screenInfo.screens[stuff->screen], client,
- pDrawable, (drm_drawable_t *)&rep.hHWDrawable)) {
- return BadValue;
- }
-
- WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXF86DRIDestroyDrawable(
- register ClientPtr client
-)
-{
- REQUEST(xXF86DRIDestroyDrawableReq);
- DrawablePtr pDrawable;
- int rc;
- REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
-
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if (!DRIDestroyDrawable(screenInfo.screens[stuff->screen], client,
- pDrawable)) {
- return BadValue;
- }
-
- return Success;
-}
-
-static int
-ProcXF86DRIGetDrawableInfo(
- register ClientPtr client
-)
-{
- xXF86DRIGetDrawableInfoReply rep;
- DrawablePtr pDrawable;
- int X, Y, W, H;
- drm_clip_rect_t * pClipRects, *pClippedRects;
- drm_clip_rect_t * pBackClipRects;
- int backX, backY, rc;
-
- REQUEST(xXF86DRIGetDrawableInfoReq);
- REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if (!DRIGetDrawableInfo( screenInfo.screens[stuff->screen],
- pDrawable,
- (unsigned int*)&rep.drawableTableIndex,
- (unsigned int*)&rep.drawableTableStamp,
- (int*)&X,
- (int*)&Y,
- (int*)&W,
- (int*)&H,
- (int*)&rep.numClipRects,
- &pClipRects,
- &backX,
- &backY,
- (int*)&rep.numBackClipRects,
- &pBackClipRects)) {
- return BadValue;
- }
-
- rep.drawableX = X;
- rep.drawableY = Y;
- rep.drawableWidth = W;
- rep.drawableHeight = H;
- rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
- SIZEOF(xGenericReply));
-
- rep.backX = backX;
- rep.backY = backY;
-
- if (rep.numBackClipRects)
- rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
-
- pClippedRects = pClipRects;
-
- if (rep.numClipRects) {
- /* Clip cliprects to screen dimensions (redirected windows) */
- pClippedRects = malloc(rep.numClipRects * sizeof(drm_clip_rect_t));
-
- if (pClippedRects) {
- ScreenPtr pScreen = screenInfo.screens[stuff->screen];
- int i, j;
-
- for (i = 0, j = 0; i < rep.numClipRects; i++) {
- pClippedRects[j].x1 = max(pClipRects[i].x1, 0);
- pClippedRects[j].y1 = max(pClipRects[i].y1, 0);
- pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width);
- pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height);
-
- if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
- pClippedRects[j].y1 < pClippedRects[j].y2) {
- j++;
- }
- }
-
- rep.numClipRects = j;
- } else {
- rep.numClipRects = 0;
- }
-
- rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
- }
-
- rep.length = bytes_to_int32(rep.length);
-
- WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
-
- if (rep.numClipRects) {
- WriteToClient(client,
- sizeof(drm_clip_rect_t) * rep.numClipRects,
- (char *)pClippedRects);
- free(pClippedRects);
- }
-
- if (rep.numBackClipRects) {
- WriteToClient(client,
- sizeof(drm_clip_rect_t) * rep.numBackClipRects,
- (char *)pBackClipRects);
- }
-
- return Success;
-}
-
-static int
-ProcXF86DRIGetDeviceInfo(
- register ClientPtr client
-)
-{
- xXF86DRIGetDeviceInfoReply rep;
- drm_handle_t hFrameBuffer;
- void *pDevPrivate;
-
- REQUEST(xXF86DRIGetDeviceInfoReq);
- REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if (!DRIGetDeviceInfo( screenInfo.screens[stuff->screen],
- &hFrameBuffer,
- (int*)&rep.framebufferOrigin,
- (int*)&rep.framebufferSize,
- (int*)&rep.framebufferStride,
- (int*)&rep.devPrivateSize,
- &pDevPrivate)) {
- return BadValue;
- }
-
- rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff);
-#if defined(LONG64) && !defined(__linux__)
- rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
-#else
- rep.hFrameBufferHigh = 0;
-#endif
-
- rep.length = 0;
- if (rep.devPrivateSize) {
- rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) -
- SIZEOF(xGenericReply) +
- pad_to_int32(rep.devPrivateSize));
- }
-
- WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
- if (rep.length) {
- WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
- }
- return Success;
-}
-
-static int
-ProcXF86DRIDispatch (
- register ClientPtr client
-)
-{
- REQUEST(xReq);
-
- switch (stuff->data)
- {
- case X_XF86DRIQueryVersion:
- return ProcXF86DRIQueryVersion(client);
- case X_XF86DRIQueryDirectRenderingCapable:
- return ProcXF86DRIQueryDirectRenderingCapable(client);
- }
-
- if (!LocalClient(client))
- return DRIErrorBase + XF86DRIClientNotLocal;
-
- switch (stuff->data)
- {
- case X_XF86DRIOpenConnection:
- return ProcXF86DRIOpenConnection(client);
- case X_XF86DRICloseConnection:
- return ProcXF86DRICloseConnection(client);
- case X_XF86DRIGetClientDriverName:
- return ProcXF86DRIGetClientDriverName(client);
- case X_XF86DRICreateContext:
- return ProcXF86DRICreateContext(client);
- case X_XF86DRIDestroyContext:
- return ProcXF86DRIDestroyContext(client);
- case X_XF86DRICreateDrawable:
- return ProcXF86DRICreateDrawable(client);
- case X_XF86DRIDestroyDrawable:
- return ProcXF86DRIDestroyDrawable(client);
- case X_XF86DRIGetDrawableInfo:
- return ProcXF86DRIGetDrawableInfo(client);
- case X_XF86DRIGetDeviceInfo:
- return ProcXF86DRIGetDeviceInfo(client);
- case X_XF86DRIAuthConnection:
- return ProcXF86DRIAuthConnection(client);
- /* {Open,Close}FullScreen are deprecated now */
- default:
- return BadRequest;
- }
-}
-
-static int
-SProcXF86DRIQueryVersion(
- register ClientPtr client
-)
-{
- register int n;
- REQUEST(xXF86DRIQueryVersionReq);
- swaps(&stuff->length, n);
- return ProcXF86DRIQueryVersion(client);
-}
-
-static int
-SProcXF86DRIQueryDirectRenderingCapable(
- register ClientPtr client
-)
-{
- register int n;
- REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
- swaps(&stuff->length, n);
- swapl(&stuff->screen, n);
- return ProcXF86DRIQueryDirectRenderingCapable(client);
-}
-
-static int
-SProcXF86DRIDispatch (
- register ClientPtr client
-)
-{
- REQUEST(xReq);
-
- /*
- * Only local clients are allowed DRI access, but remote clients still need
- * these requests to find out cleanly.
- */
- switch (stuff->data)
- {
- case X_XF86DRIQueryVersion:
- return SProcXF86DRIQueryVersion(client);
- case X_XF86DRIQueryDirectRenderingCapable:
- return SProcXF86DRIQueryDirectRenderingCapable(client);
- default:
- return DRIErrorBase + XF86DRIClientNotLocal;
- }
-}
-
-void
-XFree86DRIExtensionInit(void)
-{
- ExtensionEntry* extEntry;
-
-#ifdef XF86DRI_EVENTS
- EventType = CreateNewResourceType(XF86DRIFreeEvents, "DRIEvent");
-#endif
-
- if (
- DRIExtensionInit() &&
-#ifdef XF86DRI_EVENTS
- EventType && ScreenPrivateIndex != -1 &&
-#endif
- (extEntry = AddExtension(XF86DRINAME,
- XF86DRINumberEvents,
- XF86DRINumberErrors,
- ProcXF86DRIDispatch,
- SProcXF86DRIDispatch,
- XF86DRIResetProc,
- StandardMinorOpcode))) {
- DRIReqCode = (unsigned char)extEntry->base;
- DRIErrorBase = extEntry->errorBase;
- }
-}
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+All Rights Reserved.
+
+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, sub license, 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Jens Owen <jens@tungstengraphics.com>
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "xf86.h"
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#define _XF86DRI_SERVER_
+#include <X11/dri/xf86driproto.h>
+#include "swaprep.h"
+#include "xf86str.h"
+#include "dri.h"
+#include "sarea.h"
+#include "dristruct.h"
+#include "xf86drm.h"
+#include "protocol-versions.h"
+
+static int DRIErrorBase;
+
+
+
+static void XF86DRIResetProc(ExtensionEntry* extEntry);
+
+static unsigned char DRIReqCode = 0;
+
+extern void XFree86DRIExtensionInit(void);
+
+/*ARGSUSED*/
+static void
+XF86DRIResetProc (
+ ExtensionEntry* extEntry
+)
+{
+ DRIReset();
+}
+
+static int
+ProcXF86DRIQueryVersion(
+ register ClientPtr client
+)
+{
+ xXF86DRIQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_XF86DRI_MAJOR_VERSION;
+ rep.minorVersion = SERVER_XF86DRI_MINOR_VERSION;
+ rep.patchVersion = SERVER_XF86DRI_PATCH_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ swapl(&rep.patchVersion, n);
+ }
+ WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86DRIQueryDirectRenderingCapable(
+ register ClientPtr client
+)
+{
+ xXF86DRIQueryDirectRenderingCapableReply rep;
+ Bool isCapable;
+ register int n;
+
+ REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+ REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!DRIQueryDirectRenderingCapable( screenInfo.screens[stuff->screen],
+ &isCapable)) {
+ return BadValue;
+ }
+ rep.isCapable = isCapable;
+
+ if (!LocalClient(client) || client->swapped)
+ rep.isCapable = 0;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+
+ WriteToClient(client,
+ sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86DRIOpenConnection(
+ register ClientPtr client
+)
+{
+ xXF86DRIOpenConnectionReply rep;
+ drm_handle_t hSAREA;
+ char* busIdString;
+
+ REQUEST(xXF86DRIOpenConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ if (!DRIOpenConnection( screenInfo.screens[stuff->screen],
+ &hSAREA,
+ &busIdString)) {
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.busIdStringLength = 0;
+ if (busIdString)
+ rep.busIdStringLength = strlen(busIdString);
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
+ pad_to_int32(rep.busIdStringLength));
+
+ rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff);
+#if defined(LONG64) && !defined(__linux__)
+ rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
+#else
+ rep.hSAREAHigh = 0;
+#endif
+
+ WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
+ if (rep.busIdStringLength)
+ WriteToClient(client, rep.busIdStringLength, busIdString);
+ return Success;
+}
+
+static int
+ProcXF86DRIAuthConnection(
+ register ClientPtr client
+)
+{
+ xXF86DRIAuthConnectionReply rep;
+
+ REQUEST(xXF86DRIAuthConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.authenticated = 1;
+
+ if (!DRIAuthConnection( screenInfo.screens[stuff->screen], stuff->magic)) {
+ ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic);
+ rep.authenticated = 0;
+ }
+ WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86DRICloseConnection(
+ register ClientPtr client
+)
+{
+ REQUEST(xXF86DRICloseConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ DRICloseConnection( screenInfo.screens[stuff->screen]);
+
+ return Success;
+}
+
+static int
+ProcXF86DRIGetClientDriverName(
+ register ClientPtr client
+)
+{
+ xXF86DRIGetClientDriverNameReply rep;
+ char* clientDriverName;
+
+ REQUEST(xXF86DRIGetClientDriverNameReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ DRIGetClientDriverName( screenInfo.screens[stuff->screen],
+ (int *)&rep.ddxDriverMajorVersion,
+ (int *)&rep.ddxDriverMinorVersion,
+ (int *)&rep.ddxDriverPatchVersion,
+ &clientDriverName);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.clientDriverNameLength = 0;
+ if (clientDriverName)
+ rep.clientDriverNameLength = strlen(clientDriverName);
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) -
+ SIZEOF(xGenericReply) +
+ pad_to_int32(rep.clientDriverNameLength));
+
+ WriteToClient(client,
+ sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
+ if (rep.clientDriverNameLength)
+ WriteToClient(client,
+ rep.clientDriverNameLength,
+ clientDriverName);
+ return Success;
+}
+
+static int
+ProcXF86DRICreateContext(
+ register ClientPtr client
+)
+{
+ xXF86DRICreateContextReply rep;
+ ScreenPtr pScreen;
+
+ REQUEST(xXF86DRICreateContextReq);
+ REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ pScreen = screenInfo.screens[stuff->screen];
+
+ if (!DRICreateContext( pScreen,
+ NULL,
+ stuff->context,
+ (drm_context_t *)&rep.hHWContext)) {
+ return BadValue;
+ }
+
+ WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86DRIDestroyContext(
+ register ClientPtr client
+)
+{
+ REQUEST(xXF86DRIDestroyContextReq);
+ REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
+ stuff->context)) {
+ return BadValue;
+ }
+
+ return Success;
+}
+
+static int
+ProcXF86DRICreateDrawable(
+ ClientPtr client
+)
+{
+ xXF86DRICreateDrawableReply rep;
+ DrawablePtr pDrawable;
+ int rc;
+
+ REQUEST(xXF86DRICreateDrawableReq);
+ REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!DRICreateDrawable(screenInfo.screens[stuff->screen], client,
+ pDrawable, (drm_drawable_t *)&rep.hHWDrawable)) {
+ return BadValue;
+ }
+
+ WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86DRIDestroyDrawable(
+ register ClientPtr client
+)
+{
+ REQUEST(xXF86DRIDestroyDrawableReq);
+ DrawablePtr pDrawable;
+ int rc;
+ REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
+
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!DRIDestroyDrawable(screenInfo.screens[stuff->screen], client,
+ pDrawable)) {
+ return BadValue;
+ }
+
+ return Success;
+}
+
+static int
+ProcXF86DRIGetDrawableInfo(
+ register ClientPtr client
+)
+{
+ xXF86DRIGetDrawableInfoReply rep;
+ DrawablePtr pDrawable;
+ int X, Y, W, H;
+ drm_clip_rect_t * pClipRects, *pClippedRects;
+ drm_clip_rect_t * pBackClipRects;
+ int backX, backY, rc;
+
+ REQUEST(xXF86DRIGetDrawableInfoReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!DRIGetDrawableInfo( screenInfo.screens[stuff->screen],
+ pDrawable,
+ (unsigned int*)&rep.drawableTableIndex,
+ (unsigned int*)&rep.drawableTableStamp,
+ (int*)&X,
+ (int*)&Y,
+ (int*)&W,
+ (int*)&H,
+ (int*)&rep.numClipRects,
+ &pClipRects,
+ &backX,
+ &backY,
+ (int*)&rep.numBackClipRects,
+ &pBackClipRects)) {
+ return BadValue;
+ }
+
+ rep.drawableX = X;
+ rep.drawableY = Y;
+ rep.drawableWidth = W;
+ rep.drawableHeight = H;
+ rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
+ SIZEOF(xGenericReply));
+
+ rep.backX = backX;
+ rep.backY = backY;
+
+ if (rep.numBackClipRects)
+ rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
+
+ pClippedRects = pClipRects;
+
+ if (rep.numClipRects) {
+ /* Clip cliprects to screen dimensions (redirected windows) */
+ pClippedRects = malloc(rep.numClipRects * sizeof(drm_clip_rect_t));
+
+ if (pClippedRects) {
+ ScreenPtr pScreen = screenInfo.screens[stuff->screen];
+ int i, j;
+
+ for (i = 0, j = 0; i < rep.numClipRects; i++) {
+ pClippedRects[j].x1 = max(pClipRects[i].x1, 0);
+ pClippedRects[j].y1 = max(pClipRects[i].y1, 0);
+ pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width);
+ pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height);
+
+ if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
+ pClippedRects[j].y1 < pClippedRects[j].y2) {
+ j++;
+ }
+ }
+
+ rep.numClipRects = j;
+ } else {
+ rep.numClipRects = 0;
+ }
+
+ rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
+ }
+
+ rep.length = bytes_to_int32(rep.length);
+
+ WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
+
+ if (rep.numClipRects) {
+ WriteToClient(client,
+ sizeof(drm_clip_rect_t) * rep.numClipRects,
+ (char *)pClippedRects);
+ free(pClippedRects);
+ }
+
+ if (rep.numBackClipRects) {
+ WriteToClient(client,
+ sizeof(drm_clip_rect_t) * rep.numBackClipRects,
+ (char *)pBackClipRects);
+ }
+
+ return Success;
+}
+
+static int
+ProcXF86DRIGetDeviceInfo(
+ register ClientPtr client
+)
+{
+ xXF86DRIGetDeviceInfoReply rep;
+ drm_handle_t hFrameBuffer;
+ void *pDevPrivate;
+
+ REQUEST(xXF86DRIGetDeviceInfoReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!DRIGetDeviceInfo( screenInfo.screens[stuff->screen],
+ &hFrameBuffer,
+ (int*)&rep.framebufferOrigin,
+ (int*)&rep.framebufferSize,
+ (int*)&rep.framebufferStride,
+ (int*)&rep.devPrivateSize,
+ &pDevPrivate)) {
+ return BadValue;
+ }
+
+ rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff);
+#if defined(LONG64) && !defined(__linux__)
+ rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
+#else
+ rep.hFrameBufferHigh = 0;
+#endif
+
+ rep.length = 0;
+ if (rep.devPrivateSize) {
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) -
+ SIZEOF(xGenericReply) +
+ pad_to_int32(rep.devPrivateSize));
+ }
+
+ WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
+ if (rep.length) {
+ WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
+ }
+ return Success;
+}
+
+static int
+ProcXF86DRIDispatch (
+ register ClientPtr client
+)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_XF86DRIQueryVersion:
+ return ProcXF86DRIQueryVersion(client);
+ case X_XF86DRIQueryDirectRenderingCapable:
+ return ProcXF86DRIQueryDirectRenderingCapable(client);
+ }
+
+ if (!LocalClient(client))
+ return DRIErrorBase + XF86DRIClientNotLocal;
+
+ switch (stuff->data)
+ {
+ case X_XF86DRIOpenConnection:
+ return ProcXF86DRIOpenConnection(client);
+ case X_XF86DRICloseConnection:
+ return ProcXF86DRICloseConnection(client);
+ case X_XF86DRIGetClientDriverName:
+ return ProcXF86DRIGetClientDriverName(client);
+ case X_XF86DRICreateContext:
+ return ProcXF86DRICreateContext(client);
+ case X_XF86DRIDestroyContext:
+ return ProcXF86DRIDestroyContext(client);
+ case X_XF86DRICreateDrawable:
+ return ProcXF86DRICreateDrawable(client);
+ case X_XF86DRIDestroyDrawable:
+ return ProcXF86DRIDestroyDrawable(client);
+ case X_XF86DRIGetDrawableInfo:
+ return ProcXF86DRIGetDrawableInfo(client);
+ case X_XF86DRIGetDeviceInfo:
+ return ProcXF86DRIGetDeviceInfo(client);
+ case X_XF86DRIAuthConnection:
+ return ProcXF86DRIAuthConnection(client);
+ /* {Open,Close}FullScreen are deprecated now */
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcXF86DRIQueryVersion(
+ register ClientPtr client
+)
+{
+ register int n;
+ REQUEST(xXF86DRIQueryVersionReq);
+ swaps(&stuff->length, n);
+ return ProcXF86DRIQueryVersion(client);
+}
+
+static int
+SProcXF86DRIQueryDirectRenderingCapable(
+ register ClientPtr client
+)
+{
+ register int n;
+ REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->screen, n);
+ return ProcXF86DRIQueryDirectRenderingCapable(client);
+}
+
+static int
+SProcXF86DRIDispatch (
+ register ClientPtr client
+)
+{
+ REQUEST(xReq);
+
+ /*
+ * Only local clients are allowed DRI access, but remote clients still need
+ * these requests to find out cleanly.
+ */
+ switch (stuff->data)
+ {
+ case X_XF86DRIQueryVersion:
+ return SProcXF86DRIQueryVersion(client);
+ case X_XF86DRIQueryDirectRenderingCapable:
+ return SProcXF86DRIQueryDirectRenderingCapable(client);
+ default:
+ return DRIErrorBase + XF86DRIClientNotLocal;
+ }
+}
+
+void
+XFree86DRIExtensionInit(void)
+{
+ ExtensionEntry* extEntry;
+
+#ifdef XF86DRI_EVENTS
+ EventType = CreateNewResourceType(XF86DRIFreeEvents, "DRIEvent");
+#endif
+
+ if (
+ DRIExtensionInit() &&
+#ifdef XF86DRI_EVENTS
+ EventType && ScreenPrivateIndex != -1 &&
+#endif
+ (extEntry = AddExtension(XF86DRINAME,
+ XF86DRINumberEvents,
+ XF86DRINumberErrors,
+ ProcXF86DRIDispatch,
+ SProcXF86DRIDispatch,
+ XF86DRIResetProc,
+ StandardMinorOpcode))) {
+ DRIReqCode = (unsigned char)extEntry->base;
+ DRIErrorBase = extEntry->errorBase;
+ }
+}
diff --git a/xorg-server/hw/xfree86/dri2/dri2.c b/xorg-server/hw/xfree86/dri2/dri2.c
index 5c42a51df..ae890882b 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.c
+++ b/xorg-server/hw/xfree86/dri2/dri2.c
@@ -1,1236 +1,1236 @@
-/*
- * Copyright © 2007, 2008 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Soft-
- * ware"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, provided that the above copyright
- * notice(s) and this permission notice appear in all copies of the Soft-
- * ware and that both the above copyright notice(s) and this permission
- * notice appear in supporting documentation.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
- * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
- * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
- * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
- * QUENTIAL 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 PERFOR-
- * MANCE OF THIS SOFTWARE.
- *
- * Except as contained in this notice, the name of a copyright holder shall
- * not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization of
- * the copyright holder.
- *
- * Authors:
- * Kristian Høgsberg (krh@redhat.com)
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <errno.h>
-#ifdef WITH_LIBDRM
-#include <xf86drm.h>
-#endif
-#include "xf86Module.h"
-#include "list.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "dixstruct.h"
-#include "dri2.h"
-#include "xf86VGAarbiter.h"
-
-#include "xf86.h"
-
-CARD8 dri2_major; /* version of DRI2 supported by DDX */
-CARD8 dri2_minor;
-
-static DevPrivateKeyRec dri2ScreenPrivateKeyRec;
-#define dri2ScreenPrivateKey (&dri2ScreenPrivateKeyRec)
-
-static DevPrivateKeyRec dri2WindowPrivateKeyRec;
-#define dri2WindowPrivateKey (&dri2WindowPrivateKeyRec)
-
-static DevPrivateKeyRec dri2PixmapPrivateKeyRec;
-#define dri2PixmapPrivateKey (&dri2PixmapPrivateKeyRec)
-
-static RESTYPE dri2DrawableRes;
-
-typedef struct _DRI2Screen *DRI2ScreenPtr;
-
-typedef struct _DRI2Drawable {
- DRI2ScreenPtr dri2_screen;
- DrawablePtr drawable;
- struct list reference_list;
- int width;
- int height;
- DRI2BufferPtr *buffers;
- int bufferCount;
- unsigned int swapsPending;
- ClientPtr blockedClient;
- Bool blockedOnMsc;
- int swap_interval;
- CARD64 swap_count;
- int64_t target_sbc; /* -1 means no SBC wait outstanding */
- CARD64 last_swap_target; /* most recently queued swap target */
- CARD64 last_swap_msc; /* msc at completion of most recent swap */
- CARD64 last_swap_ust; /* ust at completion of most recent swap */
- int swap_limit; /* for N-buffering */
- unsigned long serialNumber;
-} DRI2DrawableRec, *DRI2DrawablePtr;
-
-typedef struct _DRI2Screen {
- ScreenPtr screen;
- int refcnt;
- unsigned int numDrivers;
- const char **driverNames;
- const char *deviceName;
- int fd;
- unsigned int lastSequence;
-
- DRI2CreateBufferProcPtr CreateBuffer;
- DRI2DestroyBufferProcPtr DestroyBuffer;
- DRI2CopyRegionProcPtr CopyRegion;
- DRI2ScheduleSwapProcPtr ScheduleSwap;
- DRI2GetMSCProcPtr GetMSC;
- DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
- DRI2AuthMagicProcPtr AuthMagic;
-
- HandleExposuresProcPtr HandleExposures;
-
- ConfigNotifyProcPtr ConfigNotify;
-} DRI2ScreenRec;
-
-static DRI2ScreenPtr
-DRI2GetScreen(ScreenPtr pScreen)
-{
- return dixLookupPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey);
-}
-
-static DRI2DrawablePtr
-DRI2GetDrawable(DrawablePtr pDraw)
-{
- WindowPtr pWin;
- PixmapPtr pPixmap;
-
- switch (pDraw->type) {
- case DRAWABLE_WINDOW:
- pWin = (WindowPtr) pDraw;
- return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
- case DRAWABLE_PIXMAP:
- pPixmap = (PixmapPtr) pDraw;
- return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
- default:
- return NULL;
- }
-}
-
-static unsigned long
-DRI2DrawableSerial(DrawablePtr pDraw)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- PixmapPtr pPix;
-
- if (pDraw->type != DRAWABLE_WINDOW)
- return pDraw->serialNumber;
-
- pPix = pScreen->GetWindowPixmap((WindowPtr)pDraw);
- return pPix->drawable.serialNumber;
-}
-
-static DRI2DrawablePtr
-DRI2AllocateDrawable(DrawablePtr pDraw)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- DRI2DrawablePtr pPriv;
- CARD64 ust;
- WindowPtr pWin;
- PixmapPtr pPixmap;
-
- pPriv = malloc(sizeof *pPriv);
- if (pPriv == NULL)
- return NULL;
-
- pPriv->dri2_screen = ds;
- pPriv->drawable = pDraw;
- pPriv->width = pDraw->width;
- pPriv->height = pDraw->height;
- pPriv->buffers = NULL;
- pPriv->bufferCount = 0;
- pPriv->swapsPending = 0;
- pPriv->blockedClient = NULL;
- pPriv->blockedOnMsc = FALSE;
- pPriv->swap_count = 0;
- pPriv->target_sbc = -1;
- pPriv->swap_interval = 1;
- /* Initialize last swap target from DDX if possible */
- if (!ds->GetMSC || !(*ds->GetMSC)(pDraw, &ust, &pPriv->last_swap_target))
- pPriv->last_swap_target = 0;
-
- pPriv->swap_limit = 1; /* default to double buffering */
- pPriv->last_swap_msc = 0;
- pPriv->last_swap_ust = 0;
- list_init(&pPriv->reference_list);
- pPriv->serialNumber = DRI2DrawableSerial(pDraw);
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr) pDraw;
- dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
- } else {
- pPixmap = (PixmapPtr) pDraw;
- dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, pPriv);
- }
-
- return pPriv;
-}
-
-typedef struct DRI2DrawableRefRec {
- XID id;
- XID dri2_id;
- DRI2InvalidateProcPtr invalidate;
- void *priv;
- struct list link;
-} DRI2DrawableRefRec, *DRI2DrawableRefPtr;
-
-static DRI2DrawableRefPtr
-DRI2LookupDrawableRef(DRI2DrawablePtr pPriv, XID id)
-{
- DRI2DrawableRefPtr ref;
-
- list_for_each_entry(ref, &pPriv->reference_list, link) {
- if (ref->id == id)
- return ref;
- }
-
- return NULL;
-}
-
-static int
-DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id,
- DRI2InvalidateProcPtr invalidate, void *priv)
-{
- DRI2DrawableRefPtr ref;
-
- ref = malloc(sizeof *ref);
- if (ref == NULL)
- return BadAlloc;
-
- if (!AddResource(dri2_id, dri2DrawableRes, pPriv)) {
- free(ref);
- return BadAlloc;
- }
- if (!DRI2LookupDrawableRef(pPriv, id))
- if (!AddResource(id, dri2DrawableRes, pPriv)) {
- FreeResourceByType(dri2_id, dri2DrawableRes, TRUE);
- free(ref);
- return BadAlloc;
- }
-
- ref->id = id;
- ref->dri2_id = dri2_id;
- ref->invalidate = invalidate;
- ref->priv = priv;
- list_add(&ref->link, &pPriv->reference_list);
-
- return Success;
-}
-
-int
-DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id,
- DRI2InvalidateProcPtr invalidate, void *priv)
-{
- DRI2DrawablePtr pPriv;
- XID dri2_id;
- int rc;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- pPriv = DRI2AllocateDrawable(pDraw);
- if (pPriv == NULL)
- return BadAlloc;
-
- dri2_id = FakeClientID(client->index);
- rc = DRI2AddDrawableRef(pPriv, id, dri2_id, invalidate, priv);
- if (rc != Success)
- return rc;
-
- return Success;
-}
-
-static int DRI2DrawableGone(pointer p, XID id)
-{
- DRI2DrawablePtr pPriv = p;
- DRI2ScreenPtr ds = pPriv->dri2_screen;
- DRI2DrawableRefPtr ref, next;
- WindowPtr pWin;
- PixmapPtr pPixmap;
- DrawablePtr pDraw;
- int i;
-
- list_for_each_entry_safe(ref, next, &pPriv->reference_list, link) {
- if (ref->dri2_id == id) {
- list_del(&ref->link);
- /* If this was the last ref under this X drawable XID,
- * unregister the X drawable resource. */
- if (!DRI2LookupDrawableRef(pPriv, ref->id))
- FreeResourceByType(ref->id, dri2DrawableRes, TRUE);
- free(ref);
- break;
- }
-
- if (ref->id == id) {
- list_del(&ref->link);
- FreeResourceByType(ref->dri2_id, dri2DrawableRes, TRUE);
- free(ref);
- }
- }
-
- if (!list_is_empty(&pPriv->reference_list))
- return Success;
-
- pDraw = pPriv->drawable;
- if (pDraw->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr) pDraw;
- dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
- } else {
- pPixmap = (PixmapPtr) pDraw;
- dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
- }
-
- if (pPriv->buffers != NULL) {
- for (i = 0; i < pPriv->bufferCount; i++)
- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
-
- free(pPriv->buffers);
- }
-
- free(pPriv);
-
- return Success;
-}
-
-static int
-find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
-{
- int i;
-
- if (pPriv->buffers == NULL) {
- return -1;
- }
-
- for (i = 0; i < pPriv->bufferCount; i++) {
- if ((pPriv->buffers[i] != NULL)
- && (pPriv->buffers[i]->attachment == attachment)) {
- return i;
- }
- }
-
- return -1;
-}
-
-static Bool
-allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
- DRI2DrawablePtr pPriv,
- unsigned int attachment, unsigned int format,
- int dimensions_match, DRI2BufferPtr *buffer)
-{
- int old_buf = find_attachment(pPriv, attachment);
-
- if ((old_buf < 0)
- || !dimensions_match
- || (pPriv->buffers[old_buf]->format != format)) {
- *buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
- pPriv->serialNumber = DRI2DrawableSerial(pDraw);
- return TRUE;
-
- } else {
- *buffer = pPriv->buffers[old_buf];
- pPriv->buffers[old_buf] = NULL;
- return FALSE;
- }
-}
-
-static void
-update_dri2_drawable_buffers(DRI2DrawablePtr pPriv, DrawablePtr pDraw,
- DRI2BufferPtr *buffers, int out_count, int *width, int *height)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- int i;
-
- if (pPriv->buffers != NULL) {
- for (i = 0; i < pPriv->bufferCount; i++) {
- if (pPriv->buffers[i] != NULL) {
- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
- }
- }
-
- free(pPriv->buffers);
- }
-
- pPriv->buffers = buffers;
- pPriv->bufferCount = out_count;
- pPriv->width = pDraw->width;
- pPriv->height = pDraw->height;
- *width = pPriv->width;
- *height = pPriv->height;
-}
-
-static DRI2BufferPtr *
-do_get_buffers(DrawablePtr pDraw, int *width, int *height,
- unsigned int *attachments, int count, int *out_count,
- int has_format)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
- DRI2BufferPtr *buffers;
- int need_real_front = 0;
- int need_fake_front = 0;
- int have_fake_front = 0;
- int front_format = 0;
- int dimensions_match;
- int buffers_changed = 0;
- int i;
-
- if (!pPriv) {
- *width = pDraw->width;
- *height = pDraw->height;
- *out_count = 0;
- return NULL;
- }
-
- dimensions_match = (pDraw->width == pPriv->width)
- && (pDraw->height == pPriv->height)
- && (pPriv->serialNumber == DRI2DrawableSerial(pDraw));
-
- buffers = calloc((count + 1), sizeof(buffers[0]));
- if (!buffers)
- goto err_out;
-
- for (i = 0; i < count; i++) {
- const unsigned attachment = *(attachments++);
- const unsigned format = (has_format) ? *(attachments++) : 0;
-
- if (allocate_or_reuse_buffer(pDraw, ds, pPriv, attachment,
- format, dimensions_match,
- &buffers[i]))
- buffers_changed = 1;
-
- if (buffers[i] == NULL)
- goto err_out;
-
- /* If the drawable is a window and the front-buffer is requested,
- * silently add the fake front-buffer to the list of requested
- * attachments. The counting logic in the loop accounts for the case
- * where the client requests both the fake and real front-buffer.
- */
- if (attachment == DRI2BufferBackLeft) {
- need_real_front++;
- front_format = format;
- }
-
- if (attachment == DRI2BufferFrontLeft) {
- need_real_front--;
- front_format = format;
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- need_fake_front++;
- }
- }
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- if (attachment == DRI2BufferFakeFrontLeft) {
- need_fake_front--;
- have_fake_front = 1;
- }
- }
- }
-
- if (need_real_front > 0) {
- if (allocate_or_reuse_buffer(pDraw, ds, pPriv, DRI2BufferFrontLeft,
- front_format, dimensions_match,
- &buffers[i]))
- buffers_changed = 1;
-
- if (buffers[i] == NULL)
- goto err_out;
- i++;
- }
-
- if (need_fake_front > 0) {
- if (allocate_or_reuse_buffer(pDraw, ds, pPriv, DRI2BufferFakeFrontLeft,
- front_format, dimensions_match,
- &buffers[i]))
- buffers_changed = 1;
-
- if (buffers[i] == NULL)
- goto err_out;
-
- i++;
- have_fake_front = 1;
- }
-
- *out_count = i;
-
- update_dri2_drawable_buffers(pPriv, pDraw, buffers, *out_count, width, height);
-
- /* If the client is getting a fake front-buffer, pre-fill it with the
- * contents of the real front-buffer. This ensures correct operation of
- * applications that call glXWaitX before calling glDrawBuffer.
- */
- if (have_fake_front && buffers_changed) {
- BoxRec box;
- RegionRec region;
-
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = pPriv->width;
- box.y2 = pPriv->height;
- RegionInit(&region, &box, 0);
-
- DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
- DRI2BufferFrontLeft);
- }
-
- return pPriv->buffers;
-
-err_out:
-
- *out_count = 0;
-
- if (buffers) {
- for (i = 0; i < count; i++) {
- if (buffers[i] != NULL)
- (*ds->DestroyBuffer)(pDraw, buffers[i]);
- }
-
- free(buffers);
- buffers = NULL;
- }
-
- update_dri2_drawable_buffers(pPriv, pDraw, buffers, *out_count, width, height);
-
- return buffers;
-}
-
-DRI2BufferPtr *
-DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
- unsigned int *attachments, int count, int *out_count)
-{
- return do_get_buffers(pDraw, width, height, attachments, count,
- out_count, FALSE);
-}
-
-DRI2BufferPtr *
-DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height,
- unsigned int *attachments, int count, int *out_count)
-{
- return do_get_buffers(pDraw, width, height, attachments, count,
- out_count, TRUE);
-}
-
-static void
-DRI2InvalidateDrawable(DrawablePtr pDraw)
-{
- DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
- DRI2DrawableRefPtr ref;
-
- if (!pPriv)
- return;
-
- list_for_each_entry(ref, &pPriv->reference_list, link)
- ref->invalidate(pDraw, ref->priv);
-}
-
-/*
- * In the direct rendered case, we throttle the clients that have more
- * than their share of outstanding swaps (and thus busy buffers) when a
- * new GetBuffers request is received. In the AIGLX case, we allow the
- * client to get the new buffers, but throttle when the next GLX request
- * comes in (see __glXDRIcontextWait()).
- */
-Bool
-DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw)
-{
- DRI2DrawablePtr pPriv;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return FALSE;
-
- /* Throttle to swap limit */
- if ((pPriv->swapsPending >= pPriv->swap_limit) &&
- !pPriv->blockedClient) {
- ResetCurrentRequest(client);
- client->sequence--;
- IgnoreClient(client);
- pPriv->blockedClient = client;
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-__DRI2BlockClient(ClientPtr client, DRI2DrawablePtr pPriv)
-{
- if (pPriv->blockedClient == NULL) {
- IgnoreClient(client);
- pPriv->blockedClient = client;
- }
-}
-
-void
-DRI2BlockClient(ClientPtr client, DrawablePtr pDraw)
-{
- DRI2DrawablePtr pPriv;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return;
-
- __DRI2BlockClient(client, pPriv);
- pPriv->blockedOnMsc = TRUE;
-}
-
-int
-DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
- unsigned int dest, unsigned int src)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- DRI2DrawablePtr pPriv;
- DRI2BufferPtr pDestBuffer, pSrcBuffer;
- int i;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return BadDrawable;
-
- pDestBuffer = NULL;
- pSrcBuffer = NULL;
- for (i = 0; i < pPriv->bufferCount; i++)
- {
- if (pPriv->buffers[i]->attachment == dest)
- pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i];
- if (pPriv->buffers[i]->attachment == src)
- pSrcBuffer = (DRI2BufferPtr) pPriv->buffers[i];
- }
- if (pSrcBuffer == NULL || pDestBuffer == NULL)
- return BadValue;
-
- (*ds->CopyRegion)(pDraw, pRegion, pDestBuffer, pSrcBuffer);
-
- return Success;
-}
-
-/* Can this drawable be page flipped? */
-Bool
-DRI2CanFlip(DrawablePtr pDraw)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- WindowPtr pWin, pRoot;
- PixmapPtr pWinPixmap, pRootPixmap;
-
- if (pDraw->type == DRAWABLE_PIXMAP)
- return TRUE;
-
- pRoot = pScreen->root;
- pRootPixmap = pScreen->GetWindowPixmap(pRoot);
-
- pWin = (WindowPtr) pDraw;
- pWinPixmap = pScreen->GetWindowPixmap(pWin);
- if (pRootPixmap != pWinPixmap)
- return FALSE;
- if (!RegionEqual(&pWin->clipList, &pRoot->winSize))
- return FALSE;
-
- /* Does the window match the pixmap exactly? */
- if (pDraw->x != 0 ||
- pDraw->y != 0 ||
-#ifdef COMPOSITE
- pDraw->x != pWinPixmap->screen_x ||
- pDraw->y != pWinPixmap->screen_y ||
-#endif
- pDraw->width != pWinPixmap->drawable.width ||
- pDraw->height != pWinPixmap->drawable.height)
- return FALSE;
-
- return TRUE;
-}
-
-/* Can we do a pixmap exchange instead of a blit? */
-Bool
-DRI2CanExchange(DrawablePtr pDraw)
-{
- return FALSE;
-}
-
-void
-DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
- unsigned int tv_sec, unsigned int tv_usec)
-{
- DRI2DrawablePtr pPriv;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return;
-
- ProcDRI2WaitMSCReply(client, ((CARD64)tv_sec * 1000000) + tv_usec,
- frame, pPriv->swap_count);
-
- if (pPriv->blockedClient)
- AttendClient(pPriv->blockedClient);
-
- pPriv->blockedClient = NULL;
- pPriv->blockedOnMsc = FALSE;
-}
-
-static void
-DRI2WakeClient(ClientPtr client, DrawablePtr pDraw, int frame,
- unsigned int tv_sec, unsigned int tv_usec)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- DRI2DrawablePtr pPriv;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: bad drawable\n", __func__);
- return;
- }
-
- /*
- * Swap completed.
- * Wake the client iff:
- * - it was waiting on SBC
- * - was blocked due to GLX make current
- * - was blocked due to swap throttling
- * - is not blocked due to an MSC wait
- */
- if (pPriv->target_sbc != -1 &&
- pPriv->target_sbc <= pPriv->swap_count) {
- ProcDRI2WaitMSCReply(client, ((CARD64)tv_sec * 1000000) + tv_usec,
- frame, pPriv->swap_count);
- pPriv->target_sbc = -1;
-
- AttendClient(pPriv->blockedClient);
- pPriv->blockedClient = NULL;
- } else if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) {
- if (pPriv->blockedClient) {
- AttendClient(pPriv->blockedClient);
- pPriv->blockedClient = NULL;
- }
- }
-}
-
-void
-DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
- unsigned int tv_sec, unsigned int tv_usec, int type,
- DRI2SwapEventPtr swap_complete, void *swap_data)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- DRI2DrawablePtr pPriv;
- CARD64 ust = 0;
- BoxRec box;
- RegionRec region;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: bad drawable\n", __func__);
- return;
- }
-
- pPriv->swapsPending--;
- pPriv->swap_count++;
-
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = pDraw->width;
- box.y2 = pDraw->height;
- RegionInit(&region, &box, 0);
- DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
- DRI2BufferFrontLeft);
-
- ust = ((CARD64)tv_sec * 1000000) + tv_usec;
- if (swap_complete)
- swap_complete(client, swap_data, type, ust, frame, pPriv->swap_count);
-
- pPriv->last_swap_msc = frame;
- pPriv->last_swap_ust = ust;
-
- DRI2WakeClient(client, pDraw, frame, tv_sec, tv_usec);
-}
-
-Bool
-DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable)
-{
- DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
-
- /* If we're currently waiting for a swap on this drawable, reset
- * the request and suspend the client. We only support one
- * blocked client per drawable. */
- if ((pPriv->swapsPending) &&
- pPriv->blockedClient == NULL) {
- ResetCurrentRequest(client);
- client->sequence--;
- __DRI2BlockClient(client, pPriv);
- return TRUE;
- }
-
- return FALSE;
-}
-
-int
-DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
- CARD64 divisor, CARD64 remainder, CARD64 *swap_target,
- DRI2SwapEventPtr func, void *data)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- DRI2DrawablePtr pPriv;
- DRI2BufferPtr pDestBuffer = NULL, pSrcBuffer = NULL;
- int ret, i;
- CARD64 ust, current_msc;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: bad drawable\n", __func__);
- return BadDrawable;
- }
-
- for (i = 0; i < pPriv->bufferCount; i++) {
- if (pPriv->buffers[i]->attachment == DRI2BufferFrontLeft)
- pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i];
- if (pPriv->buffers[i]->attachment == DRI2BufferBackLeft)
- pSrcBuffer = (DRI2BufferPtr) pPriv->buffers[i];
- }
- if (pSrcBuffer == NULL || pDestBuffer == NULL) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: drawable has no back or front?\n", __func__);
- return BadDrawable;
- }
-
- /* Old DDX or no swap interval, just blit */
- if (!ds->ScheduleSwap || !pPriv->swap_interval) {
- BoxRec box;
- RegionRec region;
-
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = pDraw->width;
- box.y2 = pDraw->height;
- RegionInit(&region, &box, 0);
-
- pPriv->swapsPending++;
-
- (*ds->CopyRegion)(pDraw, &region, pDestBuffer, pSrcBuffer);
- DRI2SwapComplete(client, pDraw, target_msc, 0, 0, DRI2_BLIT_COMPLETE,
- func, data);
- return Success;
- }
-
- /*
- * In the simple glXSwapBuffers case, all params will be 0, and we just
- * need to schedule a swap for the last swap target + the swap interval.
- */
- if (target_msc == 0 && divisor == 0 && remainder == 0) {
- /* If the current vblank count of the drawable's crtc is lower
- * than the count stored in last_swap_target from a previous swap
- * then reinitialize last_swap_target to the current crtc's msc,
- * otherwise the swap will hang. This will happen if the drawable
- * is moved to a crtc with a lower refresh rate, or a crtc that just
- * got enabled.
- */
- if (ds->GetMSC) {
- if (!(*ds->GetMSC)(pDraw, &ust, &current_msc))
- pPriv->last_swap_target = 0;
-
- if (current_msc < pPriv->last_swap_target)
- pPriv->last_swap_target = current_msc;
-
- }
-
- /*
- * Swap target for this swap is last swap target + swap interval since
- * we have to account for the current swap count, interval, and the
- * number of pending swaps.
- */
- *swap_target = pPriv->last_swap_target + pPriv->swap_interval;
-
- } else {
- /* glXSwapBuffersMscOML could have a 0 target_msc, honor it */
- *swap_target = target_msc;
- }
-
- pPriv->swapsPending++;
- ret = (*ds->ScheduleSwap)(client, pDraw, pDestBuffer, pSrcBuffer,
- swap_target, divisor, remainder, func, data);
- if (!ret) {
- pPriv->swapsPending--; /* didn't schedule */
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: driver failed to schedule swap\n", __func__);
- return BadDrawable;
- }
-
- pPriv->last_swap_target = *swap_target;
-
- /* According to spec, return expected swapbuffers count SBC after this swap
- * will complete.
- */
- *swap_target = pPriv->swap_count + pPriv->swapsPending;
-
- DRI2InvalidateDrawable(pDraw);
-
- return Success;
-}
-
-void
-DRI2SwapInterval(DrawablePtr pDrawable, int interval)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
-
- if (pPriv == NULL) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: bad drawable\n", __func__);
- return;
- }
-
- /* fixme: check against arbitrary max? */
- pPriv->swap_interval = interval;
-}
-
-int
-DRI2GetMSC(DrawablePtr pDraw, CARD64 *ust, CARD64 *msc, CARD64 *sbc)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- DRI2DrawablePtr pPriv;
- Bool ret;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: bad drawable\n", __func__);
- return BadDrawable;
- }
-
- if (!ds->GetMSC) {
- *ust = 0;
- *msc = 0;
- *sbc = pPriv->swap_count;
- return Success;
- }
-
- /*
- * Spec needs to be updated to include unmapped or redirected
- * drawables
- */
-
- ret = (*ds->GetMSC)(pDraw, ust, msc);
- if (!ret)
- return BadDrawable;
-
- *sbc = pPriv->swap_count;
-
- return Success;
-}
-
-int
-DRI2WaitMSC(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
- CARD64 divisor, CARD64 remainder)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- DRI2DrawablePtr pPriv;
- Bool ret;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return BadDrawable;
-
- /* Old DDX just completes immediately */
- if (!ds->ScheduleWaitMSC) {
- DRI2WaitMSCComplete(client, pDraw, target_msc, 0, 0);
-
- return Success;
- }
-
- ret = (*ds->ScheduleWaitMSC)(client, pDraw, target_msc, divisor, remainder);
- if (!ret)
- return BadDrawable;
-
- return Success;
-}
-
-int
-DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc)
-{
- DRI2DrawablePtr pPriv;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return BadDrawable;
-
- /* target_sbc == 0 means to block until all pending swaps are
- * finished. Recalculate target_sbc to get that behaviour.
- */
- if (target_sbc == 0)
- target_sbc = pPriv->swap_count + pPriv->swapsPending;
-
- /* If current swap count already >= target_sbc, reply and
- * return immediately with (ust, msc, sbc) triplet of
- * most recent completed swap.
- */
- if (pPriv->swap_count >= target_sbc) {
- ProcDRI2WaitMSCReply(client, pPriv->last_swap_ust,
- pPriv->last_swap_msc, pPriv->swap_count);
- return Success;
- }
-
- pPriv->target_sbc = target_sbc;
- __DRI2BlockClient(client, pPriv);
-
- return Success;
-}
-
-Bool
-DRI2HasSwapControl(ScreenPtr pScreen)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
-
- return ds->ScheduleSwap && ds->GetMSC;
-}
-
-Bool
-DRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd,
- const char **driverName, const char **deviceName)
-{
- DRI2ScreenPtr ds;
-
- if (!dixPrivateKeyRegistered(dri2ScreenPrivateKey))
- return FALSE;
-
- ds = DRI2GetScreen(pScreen);
- if (ds == NULL || driverType >= ds->numDrivers ||
- !ds->driverNames[driverType])
- return FALSE;
-
- *fd = ds->fd;
- *driverName = ds->driverNames[driverType];
- *deviceName = ds->deviceName;
-
- return TRUE;
-}
-
-Bool
-DRI2Authenticate(ScreenPtr pScreen, uint32_t magic)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
-
- if (ds == NULL || (*ds->AuthMagic)(ds->fd, magic))
- return FALSE;
-
- return TRUE;
-}
-
-static int
-DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
- WindowPtr pSib)
-{
- DrawablePtr pDraw = (DrawablePtr)pWin;
- ScreenPtr pScreen = pDraw->pScreen;
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
- DRI2DrawablePtr dd = DRI2GetDrawable(pDraw);
- int ret;
-
- if (ds->ConfigNotify) {
- pScreen->ConfigNotify = ds->ConfigNotify;
-
- ret = (*pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib);
-
- ds->ConfigNotify = pScreen->ConfigNotify;
- pScreen->ConfigNotify = DRI2ConfigNotify;
- if (ret)
- return ret;
- }
-
- if (!dd || (dd->width == w && dd->height == h))
- return Success;
-
- DRI2InvalidateDrawable(pDraw);
- return Success;
-}
-
-Bool
-DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
-{
- DRI2ScreenPtr ds;
- const char* driverTypeNames[] = {
- "DRI", /* DRI2DriverDRI */
- "VDPAU", /* DRI2DriverVDPAU */
- };
- unsigned int i;
- CARD8 cur_minor;
-
- if (info->version < 3)
- return FALSE;
-
- if (!xf86VGAarbiterAllowDRI(pScreen)) {
- xf86DrvMsg(pScreen->myNum, X_WARNING,
- "[DRI2] Direct rendering is not supported when VGA arb is necessary for the device\n");
- return FALSE;
- }
-
- if (!dixRegisterPrivateKey(&dri2ScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
-
- if (!dixRegisterPrivateKey(&dri2WindowPrivateKeyRec, PRIVATE_WINDOW, 0))
- return FALSE;
-
- if (!dixRegisterPrivateKey(&dri2PixmapPrivateKeyRec, PRIVATE_PIXMAP, 0))
- return FALSE;
-
- ds = calloc(1, sizeof *ds);
- if (!ds)
- return FALSE;
-
- ds->screen = pScreen;
- ds->fd = info->fd;
- ds->deviceName = info->deviceName;
- dri2_major = 1;
-
- ds->CreateBuffer = info->CreateBuffer;
- ds->DestroyBuffer = info->DestroyBuffer;
- ds->CopyRegion = info->CopyRegion;
-
- if (info->version >= 4) {
- ds->ScheduleSwap = info->ScheduleSwap;
- ds->ScheduleWaitMSC = info->ScheduleWaitMSC;
- ds->GetMSC = info->GetMSC;
- cur_minor = 3;
- } else {
- cur_minor = 1;
- }
-
- if (info->version >= 5) {
- ds->AuthMagic = info->AuthMagic;
- }
-
- /*
- * if the driver doesn't provide an AuthMagic function or the info struct
- * version is too low, it relies on the old method (using libdrm) or fail
- */
- if (!ds->AuthMagic)
-#ifdef WITH_LIBDRM
- ds->AuthMagic = drmAuthMagic;
-#else
- goto err_out;
-#endif
-
- /* Initialize minor if needed and set to minimum provied by DDX */
- if (!dri2_minor || dri2_minor > cur_minor)
- dri2_minor = cur_minor;
-
- if (info->version == 3 || info->numDrivers == 0) {
- /* Driver too old: use the old-style driverName field */
- ds->numDrivers = 1;
- ds->driverNames = malloc(sizeof(*ds->driverNames));
- if (!ds->driverNames)
- goto err_out;
- ds->driverNames[0] = info->driverName;
- } else {
- ds->numDrivers = info->numDrivers;
- ds->driverNames = malloc(info->numDrivers * sizeof(*ds->driverNames));
- if (!ds->driverNames)
- goto err_out;
- memcpy(ds->driverNames, info->driverNames,
- info->numDrivers * sizeof(*ds->driverNames));
- }
-
- dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
-
- ds->ConfigNotify = pScreen->ConfigNotify;
- pScreen->ConfigNotify = DRI2ConfigNotify;
-
- xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n");
- for (i = 0; i < sizeof(driverTypeNames) / sizeof(driverTypeNames[0]); i++) {
- if (i < ds->numDrivers && ds->driverNames[i]) {
- xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] %s driver: %s\n",
- driverTypeNames[i], ds->driverNames[i]);
- }
- }
-
- return TRUE;
-
-err_out:
- xf86DrvMsg(pScreen->myNum, X_WARNING,
- "[DRI2] Initialization failed for info version %d.\n", info->version);
- free(ds);
- return FALSE;
-}
-
-void
-DRI2CloseScreen(ScreenPtr pScreen)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
-
- free(ds->driverNames);
- free(ds);
- dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL);
-}
-
-extern ExtensionModule dri2ExtensionModule;
-
-static pointer
-DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin)
-{
- static Bool setupDone = FALSE;
-
- dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
-
- if (!setupDone)
- {
- setupDone = TRUE;
- LoadExtension(&dri2ExtensionModule, FALSE);
- }
- else
- {
- if (errmaj)
- *errmaj = LDR_ONCEONLY;
- }
-
- return (pointer) 1;
-}
-
-static XF86ModuleVersionInfo DRI2VersRec =
-{
- "dri2",
- MODULEVENDORSTRING,
- MODINFOSTRING1,
- MODINFOSTRING2,
- XORG_VERSION_CURRENT,
- 1, 2, 0,
- ABI_CLASS_EXTENSION,
- ABI_EXTENSION_VERSION,
- MOD_CLASS_NONE,
- { 0, 0, 0, 0 }
-};
-
-_X_EXPORT XF86ModuleData dri2ModuleData = { &DRI2VersRec, DRI2Setup, NULL };
-
-void
-DRI2Version(int *major, int *minor)
-{
- if (major != NULL)
- *major = DRI2VersRec.majorversion;
-
- if (minor != NULL)
- *minor = DRI2VersRec.minorversion;
-}
+/*
+ * Copyright © 2007, 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Soft-
+ * ware"), to deal in the Software without restriction, including without
+ * limitation the rights to use, copy, modify, merge, publish, distribute,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, provided that the above copyright
+ * notice(s) and this permission notice appear in all copies of the Soft-
+ * ware and that both the above copyright notice(s) and this permission
+ * notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
+ * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
+ * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
+ * QUENTIAL 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 PERFOR-
+ * MANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder shall
+ * not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization of
+ * the copyright holder.
+ *
+ * Authors:
+ * Kristian Høgsberg (krh@redhat.com)
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <errno.h>
+#ifdef WITH_LIBDRM
+#include <xf86drm.h>
+#endif
+#include "xf86Module.h"
+#include "list.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "dixstruct.h"
+#include "dri2.h"
+#include "xf86VGAarbiter.h"
+
+#include "xf86.h"
+
+CARD8 dri2_major; /* version of DRI2 supported by DDX */
+CARD8 dri2_minor;
+
+static DevPrivateKeyRec dri2ScreenPrivateKeyRec;
+#define dri2ScreenPrivateKey (&dri2ScreenPrivateKeyRec)
+
+static DevPrivateKeyRec dri2WindowPrivateKeyRec;
+#define dri2WindowPrivateKey (&dri2WindowPrivateKeyRec)
+
+static DevPrivateKeyRec dri2PixmapPrivateKeyRec;
+#define dri2PixmapPrivateKey (&dri2PixmapPrivateKeyRec)
+
+static RESTYPE dri2DrawableRes;
+
+typedef struct _DRI2Screen *DRI2ScreenPtr;
+
+typedef struct _DRI2Drawable {
+ DRI2ScreenPtr dri2_screen;
+ DrawablePtr drawable;
+ struct list reference_list;
+ int width;
+ int height;
+ DRI2BufferPtr *buffers;
+ int bufferCount;
+ unsigned int swapsPending;
+ ClientPtr blockedClient;
+ Bool blockedOnMsc;
+ int swap_interval;
+ CARD64 swap_count;
+ int64_t target_sbc; /* -1 means no SBC wait outstanding */
+ CARD64 last_swap_target; /* most recently queued swap target */
+ CARD64 last_swap_msc; /* msc at completion of most recent swap */
+ CARD64 last_swap_ust; /* ust at completion of most recent swap */
+ int swap_limit; /* for N-buffering */
+ unsigned long serialNumber;
+} DRI2DrawableRec, *DRI2DrawablePtr;
+
+typedef struct _DRI2Screen {
+ ScreenPtr screen;
+ int refcnt;
+ unsigned int numDrivers;
+ const char **driverNames;
+ const char *deviceName;
+ int fd;
+ unsigned int lastSequence;
+
+ DRI2CreateBufferProcPtr CreateBuffer;
+ DRI2DestroyBufferProcPtr DestroyBuffer;
+ DRI2CopyRegionProcPtr CopyRegion;
+ DRI2ScheduleSwapProcPtr ScheduleSwap;
+ DRI2GetMSCProcPtr GetMSC;
+ DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
+ DRI2AuthMagicProcPtr AuthMagic;
+
+ HandleExposuresProcPtr HandleExposures;
+
+ ConfigNotifyProcPtr ConfigNotify;
+} DRI2ScreenRec;
+
+static DRI2ScreenPtr
+DRI2GetScreen(ScreenPtr pScreen)
+{
+ return dixLookupPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey);
+}
+
+static DRI2DrawablePtr
+DRI2GetDrawable(DrawablePtr pDraw)
+{
+ WindowPtr pWin;
+ PixmapPtr pPixmap;
+
+ switch (pDraw->type) {
+ case DRAWABLE_WINDOW:
+ pWin = (WindowPtr) pDraw;
+ return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
+ case DRAWABLE_PIXMAP:
+ pPixmap = (PixmapPtr) pDraw;
+ return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
+ default:
+ return NULL;
+ }
+}
+
+static unsigned long
+DRI2DrawableSerial(DrawablePtr pDraw)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ PixmapPtr pPix;
+
+ if (pDraw->type != DRAWABLE_WINDOW)
+ return pDraw->serialNumber;
+
+ pPix = pScreen->GetWindowPixmap((WindowPtr)pDraw);
+ return pPix->drawable.serialNumber;
+}
+
+static DRI2DrawablePtr
+DRI2AllocateDrawable(DrawablePtr pDraw)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ CARD64 ust;
+ WindowPtr pWin;
+ PixmapPtr pPixmap;
+
+ pPriv = malloc(sizeof *pPriv);
+ if (pPriv == NULL)
+ return NULL;
+
+ pPriv->dri2_screen = ds;
+ pPriv->drawable = pDraw;
+ pPriv->width = pDraw->width;
+ pPriv->height = pDraw->height;
+ pPriv->buffers = NULL;
+ pPriv->bufferCount = 0;
+ pPriv->swapsPending = 0;
+ pPriv->blockedClient = NULL;
+ pPriv->blockedOnMsc = FALSE;
+ pPriv->swap_count = 0;
+ pPriv->target_sbc = -1;
+ pPriv->swap_interval = 1;
+ /* Initialize last swap target from DDX if possible */
+ if (!ds->GetMSC || !(*ds->GetMSC)(pDraw, &ust, &pPriv->last_swap_target))
+ pPriv->last_swap_target = 0;
+
+ pPriv->swap_limit = 1; /* default to double buffering */
+ pPriv->last_swap_msc = 0;
+ pPriv->last_swap_ust = 0;
+ list_init(&pPriv->reference_list);
+ pPriv->serialNumber = DRI2DrawableSerial(pDraw);
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ pWin = (WindowPtr) pDraw;
+ dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
+ } else {
+ pPixmap = (PixmapPtr) pDraw;
+ dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, pPriv);
+ }
+
+ return pPriv;
+}
+
+typedef struct DRI2DrawableRefRec {
+ XID id;
+ XID dri2_id;
+ DRI2InvalidateProcPtr invalidate;
+ void *priv;
+ struct list link;
+} DRI2DrawableRefRec, *DRI2DrawableRefPtr;
+
+static DRI2DrawableRefPtr
+DRI2LookupDrawableRef(DRI2DrawablePtr pPriv, XID id)
+{
+ DRI2DrawableRefPtr ref;
+
+ list_for_each_entry(ref, &pPriv->reference_list, link) {
+ if (ref->id == id)
+ return ref;
+ }
+
+ return NULL;
+}
+
+static int
+DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id,
+ DRI2InvalidateProcPtr invalidate, void *priv)
+{
+ DRI2DrawableRefPtr ref;
+
+ ref = malloc(sizeof *ref);
+ if (ref == NULL)
+ return BadAlloc;
+
+ if (!AddResource(dri2_id, dri2DrawableRes, pPriv)) {
+ free(ref);
+ return BadAlloc;
+ }
+ if (!DRI2LookupDrawableRef(pPriv, id))
+ if (!AddResource(id, dri2DrawableRes, pPriv)) {
+ FreeResourceByType(dri2_id, dri2DrawableRes, TRUE);
+ free(ref);
+ return BadAlloc;
+ }
+
+ ref->id = id;
+ ref->dri2_id = dri2_id;
+ ref->invalidate = invalidate;
+ ref->priv = priv;
+ list_add(&ref->link, &pPriv->reference_list);
+
+ return Success;
+}
+
+int
+DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id,
+ DRI2InvalidateProcPtr invalidate, void *priv)
+{
+ DRI2DrawablePtr pPriv;
+ XID dri2_id;
+ int rc;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ pPriv = DRI2AllocateDrawable(pDraw);
+ if (pPriv == NULL)
+ return BadAlloc;
+
+ dri2_id = FakeClientID(client->index);
+ rc = DRI2AddDrawableRef(pPriv, id, dri2_id, invalidate, priv);
+ if (rc != Success)
+ return rc;
+
+ return Success;
+}
+
+static int DRI2DrawableGone(pointer p, XID id)
+{
+ DRI2DrawablePtr pPriv = p;
+ DRI2ScreenPtr ds = pPriv->dri2_screen;
+ DRI2DrawableRefPtr ref, next;
+ WindowPtr pWin;
+ PixmapPtr pPixmap;
+ DrawablePtr pDraw;
+ int i;
+
+ list_for_each_entry_safe(ref, next, &pPriv->reference_list, link) {
+ if (ref->dri2_id == id) {
+ list_del(&ref->link);
+ /* If this was the last ref under this X drawable XID,
+ * unregister the X drawable resource. */
+ if (!DRI2LookupDrawableRef(pPriv, ref->id))
+ FreeResourceByType(ref->id, dri2DrawableRes, TRUE);
+ free(ref);
+ break;
+ }
+
+ if (ref->id == id) {
+ list_del(&ref->link);
+ FreeResourceByType(ref->dri2_id, dri2DrawableRes, TRUE);
+ free(ref);
+ }
+ }
+
+ if (!list_is_empty(&pPriv->reference_list))
+ return Success;
+
+ pDraw = pPriv->drawable;
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ pWin = (WindowPtr) pDraw;
+ dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
+ } else {
+ pPixmap = (PixmapPtr) pDraw;
+ dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
+ }
+
+ if (pPriv->buffers != NULL) {
+ for (i = 0; i < pPriv->bufferCount; i++)
+ (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
+
+ free(pPriv->buffers);
+ }
+
+ free(pPriv);
+
+ return Success;
+}
+
+static int
+find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
+{
+ int i;
+
+ if (pPriv->buffers == NULL) {
+ return -1;
+ }
+
+ for (i = 0; i < pPriv->bufferCount; i++) {
+ if ((pPriv->buffers[i] != NULL)
+ && (pPriv->buffers[i]->attachment == attachment)) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static Bool
+allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
+ DRI2DrawablePtr pPriv,
+ unsigned int attachment, unsigned int format,
+ int dimensions_match, DRI2BufferPtr *buffer)
+{
+ int old_buf = find_attachment(pPriv, attachment);
+
+ if ((old_buf < 0)
+ || !dimensions_match
+ || (pPriv->buffers[old_buf]->format != format)) {
+ *buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
+ pPriv->serialNumber = DRI2DrawableSerial(pDraw);
+ return TRUE;
+
+ } else {
+ *buffer = pPriv->buffers[old_buf];
+ pPriv->buffers[old_buf] = NULL;
+ return FALSE;
+ }
+}
+
+static void
+update_dri2_drawable_buffers(DRI2DrawablePtr pPriv, DrawablePtr pDraw,
+ DRI2BufferPtr *buffers, int out_count, int *width, int *height)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ int i;
+
+ if (pPriv->buffers != NULL) {
+ for (i = 0; i < pPriv->bufferCount; i++) {
+ if (pPriv->buffers[i] != NULL) {
+ (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
+ }
+ }
+
+ free(pPriv->buffers);
+ }
+
+ pPriv->buffers = buffers;
+ pPriv->bufferCount = out_count;
+ pPriv->width = pDraw->width;
+ pPriv->height = pDraw->height;
+ *width = pPriv->width;
+ *height = pPriv->height;
+}
+
+static DRI2BufferPtr *
+do_get_buffers(DrawablePtr pDraw, int *width, int *height,
+ unsigned int *attachments, int count, int *out_count,
+ int has_format)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
+ DRI2BufferPtr *buffers;
+ int need_real_front = 0;
+ int need_fake_front = 0;
+ int have_fake_front = 0;
+ int front_format = 0;
+ int dimensions_match;
+ int buffers_changed = 0;
+ int i;
+
+ if (!pPriv) {
+ *width = pDraw->width;
+ *height = pDraw->height;
+ *out_count = 0;
+ return NULL;
+ }
+
+ dimensions_match = (pDraw->width == pPriv->width)
+ && (pDraw->height == pPriv->height)
+ && (pPriv->serialNumber == DRI2DrawableSerial(pDraw));
+
+ buffers = calloc((count + 1), sizeof(buffers[0]));
+ if (!buffers)
+ goto err_out;
+
+ for (i = 0; i < count; i++) {
+ const unsigned attachment = *(attachments++);
+ const unsigned format = (has_format) ? *(attachments++) : 0;
+
+ if (allocate_or_reuse_buffer(pDraw, ds, pPriv, attachment,
+ format, dimensions_match,
+ &buffers[i]))
+ buffers_changed = 1;
+
+ if (buffers[i] == NULL)
+ goto err_out;
+
+ /* If the drawable is a window and the front-buffer is requested,
+ * silently add the fake front-buffer to the list of requested
+ * attachments. The counting logic in the loop accounts for the case
+ * where the client requests both the fake and real front-buffer.
+ */
+ if (attachment == DRI2BufferBackLeft) {
+ need_real_front++;
+ front_format = format;
+ }
+
+ if (attachment == DRI2BufferFrontLeft) {
+ need_real_front--;
+ front_format = format;
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ need_fake_front++;
+ }
+ }
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ if (attachment == DRI2BufferFakeFrontLeft) {
+ need_fake_front--;
+ have_fake_front = 1;
+ }
+ }
+ }
+
+ if (need_real_front > 0) {
+ if (allocate_or_reuse_buffer(pDraw, ds, pPriv, DRI2BufferFrontLeft,
+ front_format, dimensions_match,
+ &buffers[i]))
+ buffers_changed = 1;
+
+ if (buffers[i] == NULL)
+ goto err_out;
+ i++;
+ }
+
+ if (need_fake_front > 0) {
+ if (allocate_or_reuse_buffer(pDraw, ds, pPriv, DRI2BufferFakeFrontLeft,
+ front_format, dimensions_match,
+ &buffers[i]))
+ buffers_changed = 1;
+
+ if (buffers[i] == NULL)
+ goto err_out;
+
+ i++;
+ have_fake_front = 1;
+ }
+
+ *out_count = i;
+
+ update_dri2_drawable_buffers(pPriv, pDraw, buffers, *out_count, width, height);
+
+ /* If the client is getting a fake front-buffer, pre-fill it with the
+ * contents of the real front-buffer. This ensures correct operation of
+ * applications that call glXWaitX before calling glDrawBuffer.
+ */
+ if (have_fake_front && buffers_changed) {
+ BoxRec box;
+ RegionRec region;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pPriv->width;
+ box.y2 = pPriv->height;
+ RegionInit(&region, &box, 0);
+
+ DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
+ DRI2BufferFrontLeft);
+ }
+
+ return pPriv->buffers;
+
+err_out:
+
+ *out_count = 0;
+
+ if (buffers) {
+ for (i = 0; i < count; i++) {
+ if (buffers[i] != NULL)
+ (*ds->DestroyBuffer)(pDraw, buffers[i]);
+ }
+
+ free(buffers);
+ buffers = NULL;
+ }
+
+ update_dri2_drawable_buffers(pPriv, pDraw, buffers, *out_count, width, height);
+
+ return buffers;
+}
+
+DRI2BufferPtr *
+DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
+ unsigned int *attachments, int count, int *out_count)
+{
+ return do_get_buffers(pDraw, width, height, attachments, count,
+ out_count, FALSE);
+}
+
+DRI2BufferPtr *
+DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height,
+ unsigned int *attachments, int count, int *out_count)
+{
+ return do_get_buffers(pDraw, width, height, attachments, count,
+ out_count, TRUE);
+}
+
+static void
+DRI2InvalidateDrawable(DrawablePtr pDraw)
+{
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
+ DRI2DrawableRefPtr ref;
+
+ if (!pPriv)
+ return;
+
+ list_for_each_entry(ref, &pPriv->reference_list, link)
+ ref->invalidate(pDraw, ref->priv);
+}
+
+/*
+ * In the direct rendered case, we throttle the clients that have more
+ * than their share of outstanding swaps (and thus busy buffers) when a
+ * new GetBuffers request is received. In the AIGLX case, we allow the
+ * client to get the new buffers, but throttle when the next GLX request
+ * comes in (see __glXDRIcontextWait()).
+ */
+Bool
+DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw)
+{
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return FALSE;
+
+ /* Throttle to swap limit */
+ if ((pPriv->swapsPending >= pPriv->swap_limit) &&
+ !pPriv->blockedClient) {
+ ResetCurrentRequest(client);
+ client->sequence--;
+ IgnoreClient(client);
+ pPriv->blockedClient = client;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+__DRI2BlockClient(ClientPtr client, DRI2DrawablePtr pPriv)
+{
+ if (pPriv->blockedClient == NULL) {
+ IgnoreClient(client);
+ pPriv->blockedClient = client;
+ }
+}
+
+void
+DRI2BlockClient(ClientPtr client, DrawablePtr pDraw)
+{
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return;
+
+ __DRI2BlockClient(client, pPriv);
+ pPriv->blockedOnMsc = TRUE;
+}
+
+int
+DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
+ unsigned int dest, unsigned int src)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ DRI2BufferPtr pDestBuffer, pSrcBuffer;
+ int i;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return BadDrawable;
+
+ pDestBuffer = NULL;
+ pSrcBuffer = NULL;
+ for (i = 0; i < pPriv->bufferCount; i++)
+ {
+ if (pPriv->buffers[i]->attachment == dest)
+ pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i];
+ if (pPriv->buffers[i]->attachment == src)
+ pSrcBuffer = (DRI2BufferPtr) pPriv->buffers[i];
+ }
+ if (pSrcBuffer == NULL || pDestBuffer == NULL)
+ return BadValue;
+
+ (*ds->CopyRegion)(pDraw, pRegion, pDestBuffer, pSrcBuffer);
+
+ return Success;
+}
+
+/* Can this drawable be page flipped? */
+Bool
+DRI2CanFlip(DrawablePtr pDraw)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ WindowPtr pWin, pRoot;
+ PixmapPtr pWinPixmap, pRootPixmap;
+
+ if (pDraw->type == DRAWABLE_PIXMAP)
+ return TRUE;
+
+ pRoot = pScreen->root;
+ pRootPixmap = pScreen->GetWindowPixmap(pRoot);
+
+ pWin = (WindowPtr) pDraw;
+ pWinPixmap = pScreen->GetWindowPixmap(pWin);
+ if (pRootPixmap != pWinPixmap)
+ return FALSE;
+ if (!RegionEqual(&pWin->clipList, &pRoot->winSize))
+ return FALSE;
+
+ /* Does the window match the pixmap exactly? */
+ if (pDraw->x != 0 ||
+ pDraw->y != 0 ||
+#ifdef COMPOSITE
+ pDraw->x != pWinPixmap->screen_x ||
+ pDraw->y != pWinPixmap->screen_y ||
+#endif
+ pDraw->width != pWinPixmap->drawable.width ||
+ pDraw->height != pWinPixmap->drawable.height)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Can we do a pixmap exchange instead of a blit? */
+Bool
+DRI2CanExchange(DrawablePtr pDraw)
+{
+ return FALSE;
+}
+
+void
+DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
+ unsigned int tv_sec, unsigned int tv_usec)
+{
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return;
+
+ ProcDRI2WaitMSCReply(client, ((CARD64)tv_sec * 1000000) + tv_usec,
+ frame, pPriv->swap_count);
+
+ if (pPriv->blockedClient)
+ AttendClient(pPriv->blockedClient);
+
+ pPriv->blockedClient = NULL;
+ pPriv->blockedOnMsc = FALSE;
+}
+
+static void
+DRI2WakeClient(ClientPtr client, DrawablePtr pDraw, int frame,
+ unsigned int tv_sec, unsigned int tv_usec)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable\n", __func__);
+ return;
+ }
+
+ /*
+ * Swap completed.
+ * Wake the client iff:
+ * - it was waiting on SBC
+ * - was blocked due to GLX make current
+ * - was blocked due to swap throttling
+ * - is not blocked due to an MSC wait
+ */
+ if (pPriv->target_sbc != -1 &&
+ pPriv->target_sbc <= pPriv->swap_count) {
+ ProcDRI2WaitMSCReply(client, ((CARD64)tv_sec * 1000000) + tv_usec,
+ frame, pPriv->swap_count);
+ pPriv->target_sbc = -1;
+
+ AttendClient(pPriv->blockedClient);
+ pPriv->blockedClient = NULL;
+ } else if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) {
+ if (pPriv->blockedClient) {
+ AttendClient(pPriv->blockedClient);
+ pPriv->blockedClient = NULL;
+ }
+ }
+}
+
+void
+DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
+ unsigned int tv_sec, unsigned int tv_usec, int type,
+ DRI2SwapEventPtr swap_complete, void *swap_data)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2DrawablePtr pPriv;
+ CARD64 ust = 0;
+ BoxRec box;
+ RegionRec region;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable\n", __func__);
+ return;
+ }
+
+ pPriv->swapsPending--;
+ pPriv->swap_count++;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDraw->width;
+ box.y2 = pDraw->height;
+ RegionInit(&region, &box, 0);
+ DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
+ DRI2BufferFrontLeft);
+
+ ust = ((CARD64)tv_sec * 1000000) + tv_usec;
+ if (swap_complete)
+ swap_complete(client, swap_data, type, ust, frame, pPriv->swap_count);
+
+ pPriv->last_swap_msc = frame;
+ pPriv->last_swap_ust = ust;
+
+ DRI2WakeClient(client, pDraw, frame, tv_sec, tv_usec);
+}
+
+Bool
+DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable)
+{
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
+
+ /* If we're currently waiting for a swap on this drawable, reset
+ * the request and suspend the client. We only support one
+ * blocked client per drawable. */
+ if ((pPriv->swapsPending) &&
+ pPriv->blockedClient == NULL) {
+ ResetCurrentRequest(client);
+ client->sequence--;
+ __DRI2BlockClient(client, pPriv);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+int
+DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
+ CARD64 divisor, CARD64 remainder, CARD64 *swap_target,
+ DRI2SwapEventPtr func, void *data)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ DRI2BufferPtr pDestBuffer = NULL, pSrcBuffer = NULL;
+ int ret, i;
+ CARD64 ust, current_msc;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable\n", __func__);
+ return BadDrawable;
+ }
+
+ for (i = 0; i < pPriv->bufferCount; i++) {
+ if (pPriv->buffers[i]->attachment == DRI2BufferFrontLeft)
+ pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i];
+ if (pPriv->buffers[i]->attachment == DRI2BufferBackLeft)
+ pSrcBuffer = (DRI2BufferPtr) pPriv->buffers[i];
+ }
+ if (pSrcBuffer == NULL || pDestBuffer == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: drawable has no back or front?\n", __func__);
+ return BadDrawable;
+ }
+
+ /* Old DDX or no swap interval, just blit */
+ if (!ds->ScheduleSwap || !pPriv->swap_interval) {
+ BoxRec box;
+ RegionRec region;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDraw->width;
+ box.y2 = pDraw->height;
+ RegionInit(&region, &box, 0);
+
+ pPriv->swapsPending++;
+
+ (*ds->CopyRegion)(pDraw, &region, pDestBuffer, pSrcBuffer);
+ DRI2SwapComplete(client, pDraw, target_msc, 0, 0, DRI2_BLIT_COMPLETE,
+ func, data);
+ return Success;
+ }
+
+ /*
+ * In the simple glXSwapBuffers case, all params will be 0, and we just
+ * need to schedule a swap for the last swap target + the swap interval.
+ */
+ if (target_msc == 0 && divisor == 0 && remainder == 0) {
+ /* If the current vblank count of the drawable's crtc is lower
+ * than the count stored in last_swap_target from a previous swap
+ * then reinitialize last_swap_target to the current crtc's msc,
+ * otherwise the swap will hang. This will happen if the drawable
+ * is moved to a crtc with a lower refresh rate, or a crtc that just
+ * got enabled.
+ */
+ if (ds->GetMSC) {
+ if (!(*ds->GetMSC)(pDraw, &ust, &current_msc))
+ pPriv->last_swap_target = 0;
+
+ if (current_msc < pPriv->last_swap_target)
+ pPriv->last_swap_target = current_msc;
+
+ }
+
+ /*
+ * Swap target for this swap is last swap target + swap interval since
+ * we have to account for the current swap count, interval, and the
+ * number of pending swaps.
+ */
+ *swap_target = pPriv->last_swap_target + pPriv->swap_interval;
+
+ } else {
+ /* glXSwapBuffersMscOML could have a 0 target_msc, honor it */
+ *swap_target = target_msc;
+ }
+
+ pPriv->swapsPending++;
+ ret = (*ds->ScheduleSwap)(client, pDraw, pDestBuffer, pSrcBuffer,
+ swap_target, divisor, remainder, func, data);
+ if (!ret) {
+ pPriv->swapsPending--; /* didn't schedule */
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: driver failed to schedule swap\n", __func__);
+ return BadDrawable;
+ }
+
+ pPriv->last_swap_target = *swap_target;
+
+ /* According to spec, return expected swapbuffers count SBC after this swap
+ * will complete.
+ */
+ *swap_target = pPriv->swap_count + pPriv->swapsPending;
+
+ DRI2InvalidateDrawable(pDraw);
+
+ return Success;
+}
+
+void
+DRI2SwapInterval(DrawablePtr pDrawable, int interval)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
+
+ if (pPriv == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable\n", __func__);
+ return;
+ }
+
+ /* fixme: check against arbitrary max? */
+ pPriv->swap_interval = interval;
+}
+
+int
+DRI2GetMSC(DrawablePtr pDraw, CARD64 *ust, CARD64 *msc, CARD64 *sbc)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ Bool ret;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable\n", __func__);
+ return BadDrawable;
+ }
+
+ if (!ds->GetMSC) {
+ *ust = 0;
+ *msc = 0;
+ *sbc = pPriv->swap_count;
+ return Success;
+ }
+
+ /*
+ * Spec needs to be updated to include unmapped or redirected
+ * drawables
+ */
+
+ ret = (*ds->GetMSC)(pDraw, ust, msc);
+ if (!ret)
+ return BadDrawable;
+
+ *sbc = pPriv->swap_count;
+
+ return Success;
+}
+
+int
+DRI2WaitMSC(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
+ CARD64 divisor, CARD64 remainder)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ Bool ret;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return BadDrawable;
+
+ /* Old DDX just completes immediately */
+ if (!ds->ScheduleWaitMSC) {
+ DRI2WaitMSCComplete(client, pDraw, target_msc, 0, 0);
+
+ return Success;
+ }
+
+ ret = (*ds->ScheduleWaitMSC)(client, pDraw, target_msc, divisor, remainder);
+ if (!ret)
+ return BadDrawable;
+
+ return Success;
+}
+
+int
+DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc)
+{
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return BadDrawable;
+
+ /* target_sbc == 0 means to block until all pending swaps are
+ * finished. Recalculate target_sbc to get that behaviour.
+ */
+ if (target_sbc == 0)
+ target_sbc = pPriv->swap_count + pPriv->swapsPending;
+
+ /* If current swap count already >= target_sbc, reply and
+ * return immediately with (ust, msc, sbc) triplet of
+ * most recent completed swap.
+ */
+ if (pPriv->swap_count >= target_sbc) {
+ ProcDRI2WaitMSCReply(client, pPriv->last_swap_ust,
+ pPriv->last_swap_msc, pPriv->swap_count);
+ return Success;
+ }
+
+ pPriv->target_sbc = target_sbc;
+ __DRI2BlockClient(client, pPriv);
+
+ return Success;
+}
+
+Bool
+DRI2HasSwapControl(ScreenPtr pScreen)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+
+ return ds->ScheduleSwap && ds->GetMSC;
+}
+
+Bool
+DRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd,
+ const char **driverName, const char **deviceName)
+{
+ DRI2ScreenPtr ds;
+
+ if (!dixPrivateKeyRegistered(dri2ScreenPrivateKey))
+ return FALSE;
+
+ ds = DRI2GetScreen(pScreen);
+ if (ds == NULL || driverType >= ds->numDrivers ||
+ !ds->driverNames[driverType])
+ return FALSE;
+
+ *fd = ds->fd;
+ *driverName = ds->driverNames[driverType];
+ *deviceName = ds->deviceName;
+
+ return TRUE;
+}
+
+Bool
+DRI2Authenticate(ScreenPtr pScreen, uint32_t magic)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+
+ if (ds == NULL || (*ds->AuthMagic)(ds->fd, magic))
+ return FALSE;
+
+ return TRUE;
+}
+
+static int
+DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
+ WindowPtr pSib)
+{
+ DrawablePtr pDraw = (DrawablePtr)pWin;
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+ DRI2DrawablePtr dd = DRI2GetDrawable(pDraw);
+ int ret;
+
+ if (ds->ConfigNotify) {
+ pScreen->ConfigNotify = ds->ConfigNotify;
+
+ ret = (*pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib);
+
+ ds->ConfigNotify = pScreen->ConfigNotify;
+ pScreen->ConfigNotify = DRI2ConfigNotify;
+ if (ret)
+ return ret;
+ }
+
+ if (!dd || (dd->width == w && dd->height == h))
+ return Success;
+
+ DRI2InvalidateDrawable(pDraw);
+ return Success;
+}
+
+Bool
+DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
+{
+ DRI2ScreenPtr ds;
+ const char* driverTypeNames[] = {
+ "DRI", /* DRI2DriverDRI */
+ "VDPAU", /* DRI2DriverVDPAU */
+ };
+ unsigned int i;
+ CARD8 cur_minor;
+
+ if (info->version < 3)
+ return FALSE;
+
+ if (!xf86VGAarbiterAllowDRI(pScreen)) {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[DRI2] Direct rendering is not supported when VGA arb is necessary for the device\n");
+ return FALSE;
+ }
+
+ if (!dixRegisterPrivateKey(&dri2ScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
+ return FALSE;
+
+ if (!dixRegisterPrivateKey(&dri2WindowPrivateKeyRec, PRIVATE_WINDOW, 0))
+ return FALSE;
+
+ if (!dixRegisterPrivateKey(&dri2PixmapPrivateKeyRec, PRIVATE_PIXMAP, 0))
+ return FALSE;
+
+ ds = calloc(1, sizeof *ds);
+ if (!ds)
+ return FALSE;
+
+ ds->screen = pScreen;
+ ds->fd = info->fd;
+ ds->deviceName = info->deviceName;
+ dri2_major = 1;
+
+ ds->CreateBuffer = info->CreateBuffer;
+ ds->DestroyBuffer = info->DestroyBuffer;
+ ds->CopyRegion = info->CopyRegion;
+
+ if (info->version >= 4) {
+ ds->ScheduleSwap = info->ScheduleSwap;
+ ds->ScheduleWaitMSC = info->ScheduleWaitMSC;
+ ds->GetMSC = info->GetMSC;
+ cur_minor = 3;
+ } else {
+ cur_minor = 1;
+ }
+
+ if (info->version >= 5) {
+ ds->AuthMagic = info->AuthMagic;
+ }
+
+ /*
+ * if the driver doesn't provide an AuthMagic function or the info struct
+ * version is too low, it relies on the old method (using libdrm) or fail
+ */
+ if (!ds->AuthMagic)
+#ifdef WITH_LIBDRM
+ ds->AuthMagic = drmAuthMagic;
+#else
+ goto err_out;
+#endif
+
+ /* Initialize minor if needed and set to minimum provied by DDX */
+ if (!dri2_minor || dri2_minor > cur_minor)
+ dri2_minor = cur_minor;
+
+ if (info->version == 3 || info->numDrivers == 0) {
+ /* Driver too old: use the old-style driverName field */
+ ds->numDrivers = 1;
+ ds->driverNames = malloc(sizeof(*ds->driverNames));
+ if (!ds->driverNames)
+ goto err_out;
+ ds->driverNames[0] = info->driverName;
+ } else {
+ ds->numDrivers = info->numDrivers;
+ ds->driverNames = malloc(info->numDrivers * sizeof(*ds->driverNames));
+ if (!ds->driverNames)
+ goto err_out;
+ memcpy(ds->driverNames, info->driverNames,
+ info->numDrivers * sizeof(*ds->driverNames));
+ }
+
+ dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
+
+ ds->ConfigNotify = pScreen->ConfigNotify;
+ pScreen->ConfigNotify = DRI2ConfigNotify;
+
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n");
+ for (i = 0; i < sizeof(driverTypeNames) / sizeof(driverTypeNames[0]); i++) {
+ if (i < ds->numDrivers && ds->driverNames[i]) {
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] %s driver: %s\n",
+ driverTypeNames[i], ds->driverNames[i]);
+ }
+ }
+
+ return TRUE;
+
+err_out:
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[DRI2] Initialization failed for info version %d.\n", info->version);
+ free(ds);
+ return FALSE;
+}
+
+void
+DRI2CloseScreen(ScreenPtr pScreen)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+
+ free(ds->driverNames);
+ free(ds);
+ dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL);
+}
+
+extern ExtensionModule dri2ExtensionModule;
+
+static pointer
+DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
+
+ if (!setupDone)
+ {
+ setupDone = TRUE;
+ LoadExtension(&dri2ExtensionModule, FALSE);
+ }
+ else
+ {
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+ }
+
+ return (pointer) 1;
+}
+
+static XF86ModuleVersionInfo DRI2VersRec =
+{
+ "dri2",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ 1, 2, 0,
+ ABI_CLASS_EXTENSION,
+ ABI_EXTENSION_VERSION,
+ MOD_CLASS_NONE,
+ { 0, 0, 0, 0 }
+};
+
+_X_EXPORT XF86ModuleData dri2ModuleData = { &DRI2VersRec, DRI2Setup, NULL };
+
+void
+DRI2Version(int *major, int *minor)
+{
+ if (major != NULL)
+ *major = DRI2VersRec.majorversion;
+
+ if (minor != NULL)
+ *minor = DRI2VersRec.minorversion;
+}
diff --git a/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c b/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c
index dee731be4..d98c40be9 100644
--- a/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c
@@ -1,905 +1,905 @@
-/* all driver need this */
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-/* pci stuff */
-#include "xf86PciInfo.h"
-#include "xf86Pci.h"
-
-#include "xf86cmap.h"
-
-#include "fbdevhw.h"
-#include "fbpriv.h"
-#include "globals.h"
-#include <X11/extensions/dpmsconst.h>
-
-#define PAGE_MASK (~(getpagesize() - 1))
-
-static XF86ModuleVersionInfo fbdevHWVersRec =
-{
- "fbdevhw",
- MODULEVENDORSTRING,
- MODINFOSTRING1,
- MODINFOSTRING2,
- XORG_VERSION_CURRENT,
- 0, 0, 2,
- ABI_CLASS_VIDEODRV,
- ABI_VIDEODRV_VERSION,
- MOD_CLASS_NONE,
- {0,0,0,0}
-};
-
-_X_EXPORT XF86ModuleData fbdevhwModuleData = {
- &fbdevHWVersRec,
- NULL,
- NULL
-};
-
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-/* -------------------------------------------------------------------- */
-/* our private data, and two functions to allocate/free this */
-
-#define FBDEVHWPTRLVAL(p) (p)->privates[fbdevHWPrivateIndex].ptr
-#define FBDEVHWPTR(p) ((fbdevHWPtr)(FBDEVHWPTRLVAL(p)))
-
-static int fbdevHWPrivateIndex = -1;
-
-typedef struct {
- /* framebuffer device: filename (/dev/fb*), handle, more */
- char* device;
- int fd;
- void* fbmem;
- unsigned int fbmem_len;
- unsigned int fboff;
- char* mmio;
- unsigned int mmio_len;
-
- /* current hardware state */
- struct fb_fix_screeninfo fix;
- struct fb_var_screeninfo var;
-
- /* saved video mode */
- struct fb_var_screeninfo saved_var;
-
- /* buildin video mode */
- DisplayModeRec buildin;
-
-} fbdevHWRec, *fbdevHWPtr;
-
-Bool
-fbdevHWGetRec(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr;
-
- if (fbdevHWPrivateIndex < 0)
- fbdevHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
-
- if (FBDEVHWPTR(pScrn) != NULL)
- return TRUE;
-
- fPtr = FBDEVHWPTRLVAL(pScrn) = xnfcalloc(sizeof(fbdevHWRec), 1);
- return TRUE;
-}
-
-void
-fbdevHWFreeRec(ScrnInfoPtr pScrn)
-{
- if (fbdevHWPrivateIndex < 0)
- return;
- if (FBDEVHWPTR(pScrn) == NULL)
- return;
- free(FBDEVHWPTR(pScrn));
- FBDEVHWPTRLVAL(pScrn) = NULL;
-}
-
-int
-fbdevHWGetFD(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr;
-
- fbdevHWGetRec(pScrn);
- fPtr = FBDEVHWPTR(pScrn);
-
- return fPtr->fd;
-}
-
-/* -------------------------------------------------------------------- */
-/* some helpers for printing debug informations */
-
-#if DEBUG
-static void
-print_fbdev_mode(char *txt, struct fb_var_screeninfo *var)
-{
- ErrorF( "fbdev %s mode:\t%d %d %d %d %d %d %d %d %d %d %d:%d:%d\n",
- txt,var->pixclock,
- var->xres, var->right_margin, var->hsync_len, var->left_margin,
- var->yres, var->lower_margin, var->vsync_len, var->upper_margin,
- var->bits_per_pixel,
- var->red.length, var->green.length, var->blue.length);
-}
-
-static void
-print_xfree_mode(char *txt, DisplayModePtr mode)
-{
- ErrorF( "xfree %s mode:\t%d %d %d %d %d %d %d %d %d\n",
- txt,mode->Clock,
- mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal,
- mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal);
-}
-#endif
-
-/* -------------------------------------------------------------------- */
-/* Convert timings between the XFree and the Frame Buffer Device */
-
-static void
-xfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var)
-{
- var->xres_virtual = pScrn->displayWidth ? pScrn->displayWidth :
- pScrn->virtualX;
- var->yres_virtual = pScrn->virtualY;
- var->bits_per_pixel = pScrn->bitsPerPixel;
- if (pScrn->defaultVisual == TrueColor ||
- pScrn->defaultVisual == DirectColor) {
- var->red.length = pScrn->weight.red;
- var->green.length = pScrn->weight.green;
- var->blue.length = pScrn->weight.blue;
- } else {
- var->red.length = 8;
- var->green.length = 8;
- var->blue.length = 8;
- }
-}
-
-static void
-xfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var)
-{
- var->xres = mode->HDisplay;
- var->yres = mode->VDisplay;
- if (var->xres_virtual < var->xres)
- var->xres_virtual = var->xres;
- if (var->yres_virtual < var->yres)
- var->yres_virtual = var->yres;
- var->xoffset = var->yoffset = 0;
- var->pixclock = mode->Clock ? 1000000000/mode->Clock : 0;
- var->right_margin = mode->HSyncStart-mode->HDisplay;
- var->hsync_len = mode->HSyncEnd-mode->HSyncStart;
- var->left_margin = mode->HTotal-mode->HSyncEnd;
- var->lower_margin = mode->VSyncStart-mode->VDisplay;
- var->vsync_len = mode->VSyncEnd-mode->VSyncStart;
- var->upper_margin = mode->VTotal-mode->VSyncEnd;
- var->sync = 0;
- if (mode->Flags & V_PHSYNC)
- var->sync |= FB_SYNC_HOR_HIGH_ACT;
- if (mode->Flags & V_PVSYNC)
- var->sync |= FB_SYNC_VERT_HIGH_ACT;
- if (mode->Flags & V_PCSYNC)
- var->sync |= FB_SYNC_COMP_HIGH_ACT;
- if (mode->Flags & V_BCAST)
- var->sync |= FB_SYNC_BROADCAST;
- if (mode->Flags & V_INTERLACE)
- var->vmode = FB_VMODE_INTERLACED;
- else if (mode->Flags & V_DBLSCAN)
- var->vmode = FB_VMODE_DOUBLE;
- else
- var->vmode = FB_VMODE_NONINTERLACED;
-}
-
-static Bool
-fbdev_modes_equal(struct fb_var_screeninfo *set, struct fb_var_screeninfo *req)
-{
- return (set->xres_virtual >= req->xres_virtual &&
- set->yres_virtual >= req->yres_virtual &&
- set->bits_per_pixel == req->bits_per_pixel &&
- set->red.length == req->red.length &&
- set->green.length == req->green.length &&
- set->blue.length == req->blue.length &&
- set->xres == req->xres && set->yres == req->yres &&
- set->right_margin == req->right_margin &&
- set->hsync_len == req->hsync_len &&
- set->left_margin == req->left_margin &&
- set->lower_margin == req->lower_margin &&
- set->vsync_len == req->vsync_len &&
- set->upper_margin == req->upper_margin &&
- set->sync == req->sync && set->vmode == req->vmode);
-}
-
-static void
-fbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode)
-{
- mode->Clock = var->pixclock ? 1000000000/var->pixclock : 0;
- mode->HDisplay = var->xres;
- mode->HSyncStart = mode->HDisplay+var->right_margin;
- mode->HSyncEnd = mode->HSyncStart+var->hsync_len;
- mode->HTotal = mode->HSyncEnd+var->left_margin;
- mode->VDisplay = var->yres;
- mode->VSyncStart = mode->VDisplay+var->lower_margin;
- mode->VSyncEnd = mode->VSyncStart+var->vsync_len;
- mode->VTotal = mode->VSyncEnd+var->upper_margin;
- mode->Flags = 0;
- mode->Flags |= var->sync & FB_SYNC_HOR_HIGH_ACT ? V_PHSYNC : V_NHSYNC;
- mode->Flags |= var->sync & FB_SYNC_VERT_HIGH_ACT ? V_PVSYNC : V_NVSYNC;
- mode->Flags |= var->sync & FB_SYNC_COMP_HIGH_ACT ? V_PCSYNC : V_NCSYNC;
- if (var->sync & FB_SYNC_BROADCAST)
- mode->Flags |= V_BCAST;
- if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
- mode->Flags |= V_INTERLACE;
- else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
- mode->Flags |= V_DBLSCAN;
- mode->SynthClock = mode->Clock;
- mode->CrtcHDisplay = mode->HDisplay;
- mode->CrtcHSyncStart = mode->HSyncStart;
- mode->CrtcHSyncEnd = mode->HSyncEnd;
- mode->CrtcHTotal = mode->HTotal;
- mode->CrtcVDisplay = mode->VDisplay;
- mode->CrtcVSyncStart = mode->VSyncStart;
- mode->CrtcVSyncEnd = mode->VSyncEnd;
- mode->CrtcVTotal = mode->VTotal;
- mode->CrtcHAdjusted = FALSE;
- mode->CrtcVAdjusted = FALSE;
-}
-
-
-/* -------------------------------------------------------------------- */
-/* open correct framebuffer device */
-
-/**
- * Try to find the framebuffer device for a given PCI device
- */
-static int
-fbdev_open_pci(struct pci_device * pPci, char **namep)
-{
- struct fb_fix_screeninfo fix;
- char filename[256];
- int fd, i;
-
- for (i = 0; i < 8; i++) {
- sprintf(filename,
- "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics/fb%d",
- pPci->domain, pPci->bus, pPci->dev, pPci->func, i);
-
- fd = open(filename, O_RDONLY, 0);
- if (fd < 0) {
- sprintf(filename,
- "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics:fb%d",
- pPci->domain, pPci->bus, pPci->dev, pPci->func, i);
- fd = open(filename, O_RDONLY, 0);
- }
- if (fd >= 0) {
- close(fd);
- sprintf(filename, "/dev/fb%d", i);
-
- fd = open(filename, O_RDWR, 0);
- if (fd != -1) {
- if (ioctl(fd, FBIOGET_FSCREENINFO, (void*) & fix) != -1) {
- if (namep) {
- *namep = xnfalloc(16);
- strncpy(*namep,fix.id,16);
- }
-
- return fd;
- }
- close(fd);
- }
- }
- }
-
- if (namep)
- *namep = NULL;
-
- xf86DrvMsg(-1, X_ERROR, "Unable to find a valid framebuffer device\n");
- return -1;
-}
-
-static int
-fbdev_open(int scrnIndex, char *dev, char** namep)
-{
- struct fb_fix_screeninfo fix;
- int fd;
-
- /* try argument (from XF86Config) first */
- if (dev) {
- fd = open(dev,O_RDWR,0);
- } else {
- /* second: environment variable */
- dev = getenv("FRAMEBUFFER");
- if ((NULL == dev) || ((fd = open(dev,O_RDWR,0)) == -1)) {
- /* last try: default device */
- dev = "/dev/fb0";
- fd = open(dev,O_RDWR,0);
- }
- }
-
- if (fd == -1) {
- xf86DrvMsg(scrnIndex, X_ERROR,
- "open %s: %s\n", dev, strerror(errno));
- return -1;
- }
-
- if (namep) {
- if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)(&fix))) {
- *namep = NULL;
- xf86DrvMsg(scrnIndex, X_ERROR,
- "FBIOGET_FSCREENINFO: %s\n", strerror(errno));
- return -1;
- } else {
- *namep = xnfalloc(16);
- strncpy(*namep,fix.id,16);
- }
- }
- return fd;
-}
-
-/* -------------------------------------------------------------------- */
-
-Bool
-fbdevHWProbe(struct pci_device * pPci, char *device,char **namep)
-{
- int fd;
-
- if (pPci)
- fd = fbdev_open_pci(pPci,namep);
- else
- fd = fbdev_open(-1,device,namep);
-
- if (-1 == fd)
- return FALSE;
- close(fd);
- return TRUE;
-}
-
-Bool
-fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device * pPci, char *device)
-{
- fbdevHWPtr fPtr;
-
- fbdevHWGetRec(pScrn);
- fPtr = FBDEVHWPTR(pScrn);
-
- /* open device */
- if (pPci)
- fPtr->fd = fbdev_open_pci(pPci,NULL);
- else
- fPtr->fd = fbdev_open(pScrn->scrnIndex,device,NULL);
- if (-1 == fPtr->fd) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to open framebuffer device, consult warnings"
- " and/or errors above for possible reasons\n"
- "\t(you may have to look at the server log to see"
- " warnings)\n");
- return FALSE;
- }
-
- /* get current fb device settings */
- if (-1 == ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ioctl FBIOGET_FSCREENINFO: %s\n",
- strerror(errno));
- return FALSE;
- }
- if (-1 == ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ioctl FBIOGET_VSCREENINFO: %s\n",
- strerror(errno));
- return FALSE;
- }
-
- /* we can use the current settings as "buildin mode" */
- fbdev2xfree_timing(&fPtr->var, &fPtr->buildin);
- fPtr->buildin.name = "current";
- fPtr->buildin.next = &fPtr->buildin;
- fPtr->buildin.prev = &fPtr->buildin;
- fPtr->buildin.type |= M_T_BUILTIN;
-
- return TRUE;
-}
-
-char*
-fbdevHWGetName(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- return fPtr->fix.id;
-}
-
-int
-fbdevHWGetDepth(ScrnInfoPtr pScrn, int *fbbpp)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (fbbpp)
- *fbbpp = fPtr->var.bits_per_pixel;
-
- if (fPtr->fix.visual == FB_VISUAL_TRUECOLOR ||
- fPtr->fix.visual == FB_VISUAL_DIRECTCOLOR)
- return fPtr->var.red.length+fPtr->var.green.length+
- fPtr->var.blue.length;
- else
- return fPtr->var.bits_per_pixel;
-}
-
-int
-fbdevHWGetLineLength(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (fPtr->fix.line_length)
- return fPtr->fix.line_length;
- else
- return fPtr->var.xres_virtual*fPtr->var.bits_per_pixel/8;
-}
-
-int
-fbdevHWGetType(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- return fPtr->fix.type;
-}
-
-int
-fbdevHWGetVidmem(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- return fPtr->fix.smem_len;
-}
-
-static Bool
-fbdevHWSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool check)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- struct fb_var_screeninfo req_var = fPtr->var, set_var;
-
- xfree2fbdev_fblayout(pScrn, &req_var);
- xfree2fbdev_timing(mode, &req_var);
-
-#if DEBUG
- print_xfree_mode("init", mode);
- print_fbdev_mode("init", &req_var);
-#endif
-
- set_var = req_var;
-
- if (check)
- set_var.activate = FB_ACTIVATE_TEST;
-
- if (0 != ioctl(fPtr->fd, FBIOPUT_VSCREENINFO, (void*)(&set_var))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
- return FALSE;
- }
-
- if (!fbdev_modes_equal(&set_var, &req_var)) {
- if (!check)
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO succeeded but modified "
- "mode\n");
-#if DEBUG
- print_fbdev_mode("returned", &set_var);
-#endif
- return FALSE;
- }
-
- if (!check)
- fPtr->var = set_var;
-
- return TRUE;
-}
-
-void
-fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
-{
- char **modename;
- DisplayModePtr mode,this,last = pScrn->modes;
-
- if (NULL == pScrn->display->modes)
- return;
-
- pScrn->virtualX = pScrn->display->virtualX;
- pScrn->virtualY = pScrn->display->virtualY;
-
- for (modename = pScrn->display->modes; *modename != NULL; modename++) {
- for (mode = pScrn->monitor->Modes; mode != NULL; mode = mode->next)
- if (0 == strcmp(mode->name,*modename))
- break;
- if (NULL == mode) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "\tmode \"%s\" not found\n", *modename);
- continue;
- }
-
- if (!fbdevHWSetMode(pScrn, mode, TRUE)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "\tmode \"%s\" test failed\n", *modename);
- continue;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "\tmode \"%s\" ok\n", *modename);
-
- if (pScrn->virtualX < mode->HDisplay)
- pScrn->virtualX = mode->HDisplay;
- if (pScrn->virtualY < mode->VDisplay)
- pScrn->virtualY = mode->VDisplay;
-
- if (NULL == pScrn->modes) {
- this = pScrn->modes = xf86DuplicateMode(mode);
- this->next = this;
- this->prev = this;
- } else {
- this = xf86DuplicateMode(mode);
- this->next = pScrn->modes;
- this->prev = last;
- last->next = this;
- pScrn->modes->prev = this;
- }
- last = this;
- }
-}
-
-DisplayModePtr
-fbdevHWGetBuildinMode(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- return &fPtr->buildin;
-}
-
-void
-fbdevHWUseBuildinMode(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- pScrn->modes = &fPtr->buildin;
- pScrn->virtualX = pScrn->display->virtualX;
- pScrn->virtualY = pScrn->display->virtualY;
- if (pScrn->virtualX < fPtr->buildin.HDisplay)
- pScrn->virtualX = fPtr->buildin.HDisplay;
- if (pScrn->virtualY < fPtr->buildin.VDisplay)
- pScrn->virtualY = fPtr->buildin.VDisplay;
-}
-
-/* -------------------------------------------------------------------- */
-
-static void
-calculateFbmem_len(fbdevHWPtr fPtr)
-{
- fPtr->fboff = (unsigned long) fPtr->fix.smem_start & ~PAGE_MASK;
- fPtr->fbmem_len = (fPtr->fboff+fPtr->fix.smem_len+~PAGE_MASK) &
- PAGE_MASK;
-}
-
-
-void*
-fbdevHWMapVidmem(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (NULL == fPtr->fbmem) {
- calculateFbmem_len(fPtr);
- fPtr->fbmem = mmap(NULL, fPtr->fbmem_len, PROT_READ | PROT_WRITE,
- MAP_SHARED, fPtr->fd, 0);
- if (-1 == (long)fPtr->fbmem) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "mmap fbmem: %s\n", strerror(errno));
- fPtr->fbmem = NULL;
- } else {
- /* Perhaps we'd better add fboff to fbmem and return 0 in
- fbdevHWLinearOffset()? Of course we then need to mask
- fPtr->fbmem with PAGE_MASK in fbdevHWUnmapVidmem() as
- well. [geert] */
- }
- }
- pScrn->memPhysBase = (unsigned long)fPtr->fix.smem_start & (unsigned long)(PAGE_MASK);
- pScrn->fbOffset = (unsigned long)fPtr->fix.smem_start & (unsigned long)(~PAGE_MASK);
- return fPtr->fbmem;
-}
-
-int
-fbdevHWLinearOffset(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- return fPtr->fboff;
-}
-
-Bool
-fbdevHWUnmapVidmem(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (NULL != fPtr->fbmem) {
- if (-1 == munmap(fPtr->fbmem, fPtr->fbmem_len))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "munmap fbmem: %s\n", strerror(errno));
- fPtr->fbmem = NULL;
- }
- return TRUE;
-}
-
-void*
-fbdevHWMapMMIO(ScrnInfoPtr pScrn)
-{
- unsigned int mmio_off;
-
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (NULL == fPtr->mmio) {
- /* tell the kernel not to use accels to speed up console scrolling */
- fPtr->var.accel_flags = 0;
- if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
- return FALSE;
- }
- mmio_off = (unsigned long) fPtr->fix.mmio_start & ~PAGE_MASK;
- fPtr->mmio_len = (mmio_off+fPtr->fix.mmio_len+~PAGE_MASK) &
- PAGE_MASK;
- if (NULL == fPtr->fbmem)
- calculateFbmem_len(fPtr);
- fPtr->mmio = mmap(NULL, fPtr->mmio_len, PROT_READ | PROT_WRITE,
- MAP_SHARED, fPtr->fd, fPtr->fbmem_len);
- if (-1 == (long)fPtr->mmio) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "mmap mmio: %s\n", strerror(errno));
- fPtr->mmio = NULL;
- } else
- fPtr->mmio += mmio_off;
- }
- return fPtr->mmio;
-}
-
-Bool
-fbdevHWUnmapMMIO(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (NULL != fPtr->mmio) {
- if (-1 == munmap((void *)((unsigned long)fPtr->mmio & PAGE_MASK), fPtr->mmio_len))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "munmap mmio: %s\n", strerror(errno));
- fPtr->mmio = NULL;
- /* FIXME: restore var.accel_flags [geert] */
- }
- return TRUE;
-}
-
-/* -------------------------------------------------------------------- */
-
-Bool
-fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- pScrn->vtSema = TRUE;
-
- /* set */
- if (!fbdevHWSetMode(pScrn, mode, FALSE))
- return FALSE;
-
- /* read back */
- if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOGET_FSCREENINFO: %s\n", strerror(errno));
- return FALSE;
- }
- if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOGET_VSCREENINFO: %s\n", strerror(errno));
- return FALSE;
- }
-
- if (pScrn->defaultVisual == TrueColor ||
- pScrn->defaultVisual == DirectColor) {
- /* XXX: This is a hack, but it should be a NOP for all the setups that
- * worked before and actually seems to fix some others...
- */
- pScrn->offset.red = fPtr->var.red.offset;
- pScrn->offset.green = fPtr->var.green.offset;
- pScrn->offset.blue = fPtr->var.blue.offset;
- pScrn->mask.red = ((1 << fPtr->var.red.length) - 1) << fPtr->var.red.offset;
- pScrn->mask.green = ((1 << fPtr->var.green.length) - 1) << fPtr->var.green.offset;
- pScrn->mask.blue = ((1 << fPtr->var.blue.length) - 1) << fPtr->var.blue.offset;
- }
-
- return TRUE;
-}
-
-/* -------------------------------------------------------------------- */
-/* video mode save/restore */
-void
-fbdevHWSave(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->saved_var)))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOGET_VSCREENINFO: %s\n", strerror(errno));
-}
-
-void
-fbdevHWRestore(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->saved_var)))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
-}
-
-/* -------------------------------------------------------------------- */
-/* callback for xf86HandleColormaps */
-
-void
-fbdevHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
- LOCO *colors, VisualPtr pVisual)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- struct fb_cmap cmap;
- unsigned short red,green,blue;
- int i;
-
- cmap.len = 1;
- cmap.red = &red;
- cmap.green = &green;
- cmap.blue = &blue;
- cmap.transp = NULL;
- for (i = 0; i < numColors; i++) {
- cmap.start = indices[i];
- red = (colors[indices[i]].red << 8) |
- colors[indices[i]].red;
- green = (colors[indices[i]].green << 8) |
- colors[indices[i]].green;
- blue = (colors[indices[i]].blue << 8) |
- colors[indices[i]].blue;
- if (-1 == ioctl(fPtr->fd,FBIOPUTCMAP,(void*)&cmap))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUTCMAP: %s\n", strerror(errno));
- }
-}
-
-/* -------------------------------------------------------------------- */
-/* these can be hooked directly into ScrnInfoRec */
-
-ModeStatus
-fbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
- if (!fbdevHWSetMode(pScrn, mode, TRUE))
- return MODE_BAD;
-
- return MODE_OK;
-}
-
-Bool
-fbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
-
- if (!fbdevHWSetMode(pScrn, mode, FALSE))
- return FALSE;
-
- return TRUE;
-}
-
-void
-fbdevHWAdjustFrame(int scrnIndex, int x, int y, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if ( x < 0 || x + fPtr->var.xres > fPtr->var.xres_virtual ||
- y < 0 || y + fPtr->var.yres > fPtr->var.yres_virtual )
- return;
-
- fPtr->var.xoffset = x;
- fPtr->var.yoffset = y;
- if (-1 == ioctl(fPtr->fd,FBIOPAN_DISPLAY,(void*)&fPtr->var))
- xf86DrvMsgVerb(scrnIndex, X_WARNING, 5,
- "FBIOPAN_DISPLAY: %s\n", strerror(errno));
-}
-
-Bool
-fbdevHWEnterVT(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
- if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
- return FALSE;
- fbdevHWAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
- return TRUE;
-}
-
-void
-fbdevHWLeaveVT(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
- fbdevHWRestore(pScrn);
-}
-
-void
-fbdevHWDPMSSet(ScrnInfoPtr pScrn, int mode, int flags)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- unsigned long fbmode;
-
- if (!pScrn->vtSema)
- return;
-
- switch (mode) {
- case DPMSModeOn:
- fbmode = 0;
- break;
- case DPMSModeStandby:
- fbmode = 2;
- break;
- case DPMSModeSuspend:
- fbmode = 3;
- break;
- case DPMSModeOff:
- fbmode = 4;
- break;
- default:
- return;
- }
-
- if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *)fbmode))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOBLANK: %s\n", strerror(errno));
-}
-
-Bool
-fbdevHWSaveScreen(ScreenPtr pScreen, int mode)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- unsigned long unblank;
-
- if (!pScrn->vtSema)
- return TRUE;
-
- unblank = xf86IsUnblank(mode);
-
- if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *)(1-unblank))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOBLANK: %s\n", strerror(errno));
- return FALSE;
- }
-
- return TRUE;
-}
-
-xf86SwitchModeProc *
-fbdevHWSwitchModeWeak(void) { return fbdevHWSwitchMode; }
-
-xf86AdjustFrameProc *
-fbdevHWAdjustFrameWeak(void) { return fbdevHWAdjustFrame; }
-
-xf86EnterVTProc *
-fbdevHWEnterVTWeak(void) { return fbdevHWEnterVT; }
-
-xf86LeaveVTProc *
-fbdevHWLeaveVTWeak(void) { return fbdevHWLeaveVT; }
-
-xf86ValidModeProc *
-fbdevHWValidModeWeak(void) { return fbdevHWValidMode; }
-
-xf86DPMSSetProc *
-fbdevHWDPMSSetWeak(void) { return fbdevHWDPMSSet; }
-
-xf86LoadPaletteProc *
-fbdevHWLoadPaletteWeak(void) { return fbdevHWLoadPalette; }
-
-SaveScreenProcPtr
-fbdevHWSaveScreenWeak(void) { return fbdevHWSaveScreen; }
+/* all driver need this */
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+/* pci stuff */
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "xf86cmap.h"
+
+#include "fbdevhw.h"
+#include "fbpriv.h"
+#include "globals.h"
+#include <X11/extensions/dpmsconst.h>
+
+#define PAGE_MASK (~(getpagesize() - 1))
+
+static XF86ModuleVersionInfo fbdevHWVersRec =
+{
+ "fbdevhw",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ 0, 0, 2,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0}
+};
+
+_X_EXPORT XF86ModuleData fbdevhwModuleData = {
+ &fbdevHWVersRec,
+ NULL,
+ NULL
+};
+
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* -------------------------------------------------------------------- */
+/* our private data, and two functions to allocate/free this */
+
+#define FBDEVHWPTRLVAL(p) (p)->privates[fbdevHWPrivateIndex].ptr
+#define FBDEVHWPTR(p) ((fbdevHWPtr)(FBDEVHWPTRLVAL(p)))
+
+static int fbdevHWPrivateIndex = -1;
+
+typedef struct {
+ /* framebuffer device: filename (/dev/fb*), handle, more */
+ char* device;
+ int fd;
+ void* fbmem;
+ unsigned int fbmem_len;
+ unsigned int fboff;
+ char* mmio;
+ unsigned int mmio_len;
+
+ /* current hardware state */
+ struct fb_fix_screeninfo fix;
+ struct fb_var_screeninfo var;
+
+ /* saved video mode */
+ struct fb_var_screeninfo saved_var;
+
+ /* buildin video mode */
+ DisplayModeRec buildin;
+
+} fbdevHWRec, *fbdevHWPtr;
+
+Bool
+fbdevHWGetRec(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr;
+
+ if (fbdevHWPrivateIndex < 0)
+ fbdevHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
+
+ if (FBDEVHWPTR(pScrn) != NULL)
+ return TRUE;
+
+ fPtr = FBDEVHWPTRLVAL(pScrn) = xnfcalloc(sizeof(fbdevHWRec), 1);
+ return TRUE;
+}
+
+void
+fbdevHWFreeRec(ScrnInfoPtr pScrn)
+{
+ if (fbdevHWPrivateIndex < 0)
+ return;
+ if (FBDEVHWPTR(pScrn) == NULL)
+ return;
+ free(FBDEVHWPTR(pScrn));
+ FBDEVHWPTRLVAL(pScrn) = NULL;
+}
+
+int
+fbdevHWGetFD(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr;
+
+ fbdevHWGetRec(pScrn);
+ fPtr = FBDEVHWPTR(pScrn);
+
+ return fPtr->fd;
+}
+
+/* -------------------------------------------------------------------- */
+/* some helpers for printing debug informations */
+
+#if DEBUG
+static void
+print_fbdev_mode(char *txt, struct fb_var_screeninfo *var)
+{
+ ErrorF( "fbdev %s mode:\t%d %d %d %d %d %d %d %d %d %d %d:%d:%d\n",
+ txt,var->pixclock,
+ var->xres, var->right_margin, var->hsync_len, var->left_margin,
+ var->yres, var->lower_margin, var->vsync_len, var->upper_margin,
+ var->bits_per_pixel,
+ var->red.length, var->green.length, var->blue.length);
+}
+
+static void
+print_xfree_mode(char *txt, DisplayModePtr mode)
+{
+ ErrorF( "xfree %s mode:\t%d %d %d %d %d %d %d %d %d\n",
+ txt,mode->Clock,
+ mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal,
+ mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal);
+}
+#endif
+
+/* -------------------------------------------------------------------- */
+/* Convert timings between the XFree and the Frame Buffer Device */
+
+static void
+xfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var)
+{
+ var->xres_virtual = pScrn->displayWidth ? pScrn->displayWidth :
+ pScrn->virtualX;
+ var->yres_virtual = pScrn->virtualY;
+ var->bits_per_pixel = pScrn->bitsPerPixel;
+ if (pScrn->defaultVisual == TrueColor ||
+ pScrn->defaultVisual == DirectColor) {
+ var->red.length = pScrn->weight.red;
+ var->green.length = pScrn->weight.green;
+ var->blue.length = pScrn->weight.blue;
+ } else {
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ }
+}
+
+static void
+xfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var)
+{
+ var->xres = mode->HDisplay;
+ var->yres = mode->VDisplay;
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+ if (var->yres_virtual < var->yres)
+ var->yres_virtual = var->yres;
+ var->xoffset = var->yoffset = 0;
+ var->pixclock = mode->Clock ? 1000000000/mode->Clock : 0;
+ var->right_margin = mode->HSyncStart-mode->HDisplay;
+ var->hsync_len = mode->HSyncEnd-mode->HSyncStart;
+ var->left_margin = mode->HTotal-mode->HSyncEnd;
+ var->lower_margin = mode->VSyncStart-mode->VDisplay;
+ var->vsync_len = mode->VSyncEnd-mode->VSyncStart;
+ var->upper_margin = mode->VTotal-mode->VSyncEnd;
+ var->sync = 0;
+ if (mode->Flags & V_PHSYNC)
+ var->sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (mode->Flags & V_PVSYNC)
+ var->sync |= FB_SYNC_VERT_HIGH_ACT;
+ if (mode->Flags & V_PCSYNC)
+ var->sync |= FB_SYNC_COMP_HIGH_ACT;
+ if (mode->Flags & V_BCAST)
+ var->sync |= FB_SYNC_BROADCAST;
+ if (mode->Flags & V_INTERLACE)
+ var->vmode = FB_VMODE_INTERLACED;
+ else if (mode->Flags & V_DBLSCAN)
+ var->vmode = FB_VMODE_DOUBLE;
+ else
+ var->vmode = FB_VMODE_NONINTERLACED;
+}
+
+static Bool
+fbdev_modes_equal(struct fb_var_screeninfo *set, struct fb_var_screeninfo *req)
+{
+ return (set->xres_virtual >= req->xres_virtual &&
+ set->yres_virtual >= req->yres_virtual &&
+ set->bits_per_pixel == req->bits_per_pixel &&
+ set->red.length == req->red.length &&
+ set->green.length == req->green.length &&
+ set->blue.length == req->blue.length &&
+ set->xres == req->xres && set->yres == req->yres &&
+ set->right_margin == req->right_margin &&
+ set->hsync_len == req->hsync_len &&
+ set->left_margin == req->left_margin &&
+ set->lower_margin == req->lower_margin &&
+ set->vsync_len == req->vsync_len &&
+ set->upper_margin == req->upper_margin &&
+ set->sync == req->sync && set->vmode == req->vmode);
+}
+
+static void
+fbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode)
+{
+ mode->Clock = var->pixclock ? 1000000000/var->pixclock : 0;
+ mode->HDisplay = var->xres;
+ mode->HSyncStart = mode->HDisplay+var->right_margin;
+ mode->HSyncEnd = mode->HSyncStart+var->hsync_len;
+ mode->HTotal = mode->HSyncEnd+var->left_margin;
+ mode->VDisplay = var->yres;
+ mode->VSyncStart = mode->VDisplay+var->lower_margin;
+ mode->VSyncEnd = mode->VSyncStart+var->vsync_len;
+ mode->VTotal = mode->VSyncEnd+var->upper_margin;
+ mode->Flags = 0;
+ mode->Flags |= var->sync & FB_SYNC_HOR_HIGH_ACT ? V_PHSYNC : V_NHSYNC;
+ mode->Flags |= var->sync & FB_SYNC_VERT_HIGH_ACT ? V_PVSYNC : V_NVSYNC;
+ mode->Flags |= var->sync & FB_SYNC_COMP_HIGH_ACT ? V_PCSYNC : V_NCSYNC;
+ if (var->sync & FB_SYNC_BROADCAST)
+ mode->Flags |= V_BCAST;
+ if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
+ mode->Flags |= V_INTERLACE;
+ else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
+ mode->Flags |= V_DBLSCAN;
+ mode->SynthClock = mode->Clock;
+ mode->CrtcHDisplay = mode->HDisplay;
+ mode->CrtcHSyncStart = mode->HSyncStart;
+ mode->CrtcHSyncEnd = mode->HSyncEnd;
+ mode->CrtcHTotal = mode->HTotal;
+ mode->CrtcVDisplay = mode->VDisplay;
+ mode->CrtcVSyncStart = mode->VSyncStart;
+ mode->CrtcVSyncEnd = mode->VSyncEnd;
+ mode->CrtcVTotal = mode->VTotal;
+ mode->CrtcHAdjusted = FALSE;
+ mode->CrtcVAdjusted = FALSE;
+}
+
+
+/* -------------------------------------------------------------------- */
+/* open correct framebuffer device */
+
+/**
+ * Try to find the framebuffer device for a given PCI device
+ */
+static int
+fbdev_open_pci(struct pci_device * pPci, char **namep)
+{
+ struct fb_fix_screeninfo fix;
+ char filename[256];
+ int fd, i;
+
+ for (i = 0; i < 8; i++) {
+ sprintf(filename,
+ "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics/fb%d",
+ pPci->domain, pPci->bus, pPci->dev, pPci->func, i);
+
+ fd = open(filename, O_RDONLY, 0);
+ if (fd < 0) {
+ sprintf(filename,
+ "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics:fb%d",
+ pPci->domain, pPci->bus, pPci->dev, pPci->func, i);
+ fd = open(filename, O_RDONLY, 0);
+ }
+ if (fd >= 0) {
+ close(fd);
+ sprintf(filename, "/dev/fb%d", i);
+
+ fd = open(filename, O_RDWR, 0);
+ if (fd != -1) {
+ if (ioctl(fd, FBIOGET_FSCREENINFO, (void*) & fix) != -1) {
+ if (namep) {
+ *namep = xnfalloc(16);
+ strncpy(*namep,fix.id,16);
+ }
+
+ return fd;
+ }
+ close(fd);
+ }
+ }
+ }
+
+ if (namep)
+ *namep = NULL;
+
+ xf86DrvMsg(-1, X_ERROR, "Unable to find a valid framebuffer device\n");
+ return -1;
+}
+
+static int
+fbdev_open(int scrnIndex, char *dev, char** namep)
+{
+ struct fb_fix_screeninfo fix;
+ int fd;
+
+ /* try argument (from XF86Config) first */
+ if (dev) {
+ fd = open(dev,O_RDWR,0);
+ } else {
+ /* second: environment variable */
+ dev = getenv("FRAMEBUFFER");
+ if ((NULL == dev) || ((fd = open(dev,O_RDWR,0)) == -1)) {
+ /* last try: default device */
+ dev = "/dev/fb0";
+ fd = open(dev,O_RDWR,0);
+ }
+ }
+
+ if (fd == -1) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "open %s: %s\n", dev, strerror(errno));
+ return -1;
+ }
+
+ if (namep) {
+ if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)(&fix))) {
+ *namep = NULL;
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "FBIOGET_FSCREENINFO: %s\n", strerror(errno));
+ return -1;
+ } else {
+ *namep = xnfalloc(16);
+ strncpy(*namep,fix.id,16);
+ }
+ }
+ return fd;
+}
+
+/* -------------------------------------------------------------------- */
+
+Bool
+fbdevHWProbe(struct pci_device * pPci, char *device,char **namep)
+{
+ int fd;
+
+ if (pPci)
+ fd = fbdev_open_pci(pPci,namep);
+ else
+ fd = fbdev_open(-1,device,namep);
+
+ if (-1 == fd)
+ return FALSE;
+ close(fd);
+ return TRUE;
+}
+
+Bool
+fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device * pPci, char *device)
+{
+ fbdevHWPtr fPtr;
+
+ fbdevHWGetRec(pScrn);
+ fPtr = FBDEVHWPTR(pScrn);
+
+ /* open device */
+ if (pPci)
+ fPtr->fd = fbdev_open_pci(pPci,NULL);
+ else
+ fPtr->fd = fbdev_open(pScrn->scrnIndex,device,NULL);
+ if (-1 == fPtr->fd) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to open framebuffer device, consult warnings"
+ " and/or errors above for possible reasons\n"
+ "\t(you may have to look at the server log to see"
+ " warnings)\n");
+ return FALSE;
+ }
+
+ /* get current fb device settings */
+ if (-1 == ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ioctl FBIOGET_FSCREENINFO: %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+ if (-1 == ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ioctl FBIOGET_VSCREENINFO: %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+
+ /* we can use the current settings as "buildin mode" */
+ fbdev2xfree_timing(&fPtr->var, &fPtr->buildin);
+ fPtr->buildin.name = "current";
+ fPtr->buildin.next = &fPtr->buildin;
+ fPtr->buildin.prev = &fPtr->buildin;
+ fPtr->buildin.type |= M_T_BUILTIN;
+
+ return TRUE;
+}
+
+char*
+fbdevHWGetName(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ return fPtr->fix.id;
+}
+
+int
+fbdevHWGetDepth(ScrnInfoPtr pScrn, int *fbbpp)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ if (fbbpp)
+ *fbbpp = fPtr->var.bits_per_pixel;
+
+ if (fPtr->fix.visual == FB_VISUAL_TRUECOLOR ||
+ fPtr->fix.visual == FB_VISUAL_DIRECTCOLOR)
+ return fPtr->var.red.length+fPtr->var.green.length+
+ fPtr->var.blue.length;
+ else
+ return fPtr->var.bits_per_pixel;
+}
+
+int
+fbdevHWGetLineLength(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ if (fPtr->fix.line_length)
+ return fPtr->fix.line_length;
+ else
+ return fPtr->var.xres_virtual*fPtr->var.bits_per_pixel/8;
+}
+
+int
+fbdevHWGetType(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ return fPtr->fix.type;
+}
+
+int
+fbdevHWGetVidmem(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ return fPtr->fix.smem_len;
+}
+
+static Bool
+fbdevHWSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool check)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ struct fb_var_screeninfo req_var = fPtr->var, set_var;
+
+ xfree2fbdev_fblayout(pScrn, &req_var);
+ xfree2fbdev_timing(mode, &req_var);
+
+#if DEBUG
+ print_xfree_mode("init", mode);
+ print_fbdev_mode("init", &req_var);
+#endif
+
+ set_var = req_var;
+
+ if (check)
+ set_var.activate = FB_ACTIVATE_TEST;
+
+ if (0 != ioctl(fPtr->fd, FBIOPUT_VSCREENINFO, (void*)(&set_var))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+ return FALSE;
+ }
+
+ if (!fbdev_modes_equal(&set_var, &req_var)) {
+ if (!check)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOPUT_VSCREENINFO succeeded but modified "
+ "mode\n");
+#if DEBUG
+ print_fbdev_mode("returned", &set_var);
+#endif
+ return FALSE;
+ }
+
+ if (!check)
+ fPtr->var = set_var;
+
+ return TRUE;
+}
+
+void
+fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
+{
+ char **modename;
+ DisplayModePtr mode,this,last = pScrn->modes;
+
+ if (NULL == pScrn->display->modes)
+ return;
+
+ pScrn->virtualX = pScrn->display->virtualX;
+ pScrn->virtualY = pScrn->display->virtualY;
+
+ for (modename = pScrn->display->modes; *modename != NULL; modename++) {
+ for (mode = pScrn->monitor->Modes; mode != NULL; mode = mode->next)
+ if (0 == strcmp(mode->name,*modename))
+ break;
+ if (NULL == mode) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "\tmode \"%s\" not found\n", *modename);
+ continue;
+ }
+
+ if (!fbdevHWSetMode(pScrn, mode, TRUE)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "\tmode \"%s\" test failed\n", *modename);
+ continue;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "\tmode \"%s\" ok\n", *modename);
+
+ if (pScrn->virtualX < mode->HDisplay)
+ pScrn->virtualX = mode->HDisplay;
+ if (pScrn->virtualY < mode->VDisplay)
+ pScrn->virtualY = mode->VDisplay;
+
+ if (NULL == pScrn->modes) {
+ this = pScrn->modes = xf86DuplicateMode(mode);
+ this->next = this;
+ this->prev = this;
+ } else {
+ this = xf86DuplicateMode(mode);
+ this->next = pScrn->modes;
+ this->prev = last;
+ last->next = this;
+ pScrn->modes->prev = this;
+ }
+ last = this;
+ }
+}
+
+DisplayModePtr
+fbdevHWGetBuildinMode(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ return &fPtr->buildin;
+}
+
+void
+fbdevHWUseBuildinMode(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ pScrn->modes = &fPtr->buildin;
+ pScrn->virtualX = pScrn->display->virtualX;
+ pScrn->virtualY = pScrn->display->virtualY;
+ if (pScrn->virtualX < fPtr->buildin.HDisplay)
+ pScrn->virtualX = fPtr->buildin.HDisplay;
+ if (pScrn->virtualY < fPtr->buildin.VDisplay)
+ pScrn->virtualY = fPtr->buildin.VDisplay;
+}
+
+/* -------------------------------------------------------------------- */
+
+static void
+calculateFbmem_len(fbdevHWPtr fPtr)
+{
+ fPtr->fboff = (unsigned long) fPtr->fix.smem_start & ~PAGE_MASK;
+ fPtr->fbmem_len = (fPtr->fboff+fPtr->fix.smem_len+~PAGE_MASK) &
+ PAGE_MASK;
+}
+
+
+void*
+fbdevHWMapVidmem(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ if (NULL == fPtr->fbmem) {
+ calculateFbmem_len(fPtr);
+ fPtr->fbmem = mmap(NULL, fPtr->fbmem_len, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fPtr->fd, 0);
+ if (-1 == (long)fPtr->fbmem) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "mmap fbmem: %s\n", strerror(errno));
+ fPtr->fbmem = NULL;
+ } else {
+ /* Perhaps we'd better add fboff to fbmem and return 0 in
+ fbdevHWLinearOffset()? Of course we then need to mask
+ fPtr->fbmem with PAGE_MASK in fbdevHWUnmapVidmem() as
+ well. [geert] */
+ }
+ }
+ pScrn->memPhysBase = (unsigned long)fPtr->fix.smem_start & (unsigned long)(PAGE_MASK);
+ pScrn->fbOffset = (unsigned long)fPtr->fix.smem_start & (unsigned long)(~PAGE_MASK);
+ return fPtr->fbmem;
+}
+
+int
+fbdevHWLinearOffset(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ return fPtr->fboff;
+}
+
+Bool
+fbdevHWUnmapVidmem(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ if (NULL != fPtr->fbmem) {
+ if (-1 == munmap(fPtr->fbmem, fPtr->fbmem_len))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "munmap fbmem: %s\n", strerror(errno));
+ fPtr->fbmem = NULL;
+ }
+ return TRUE;
+}
+
+void*
+fbdevHWMapMMIO(ScrnInfoPtr pScrn)
+{
+ unsigned int mmio_off;
+
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ if (NULL == fPtr->mmio) {
+ /* tell the kernel not to use accels to speed up console scrolling */
+ fPtr->var.accel_flags = 0;
+ if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+ return FALSE;
+ }
+ mmio_off = (unsigned long) fPtr->fix.mmio_start & ~PAGE_MASK;
+ fPtr->mmio_len = (mmio_off+fPtr->fix.mmio_len+~PAGE_MASK) &
+ PAGE_MASK;
+ if (NULL == fPtr->fbmem)
+ calculateFbmem_len(fPtr);
+ fPtr->mmio = mmap(NULL, fPtr->mmio_len, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fPtr->fd, fPtr->fbmem_len);
+ if (-1 == (long)fPtr->mmio) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "mmap mmio: %s\n", strerror(errno));
+ fPtr->mmio = NULL;
+ } else
+ fPtr->mmio += mmio_off;
+ }
+ return fPtr->mmio;
+}
+
+Bool
+fbdevHWUnmapMMIO(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ if (NULL != fPtr->mmio) {
+ if (-1 == munmap((void *)((unsigned long)fPtr->mmio & PAGE_MASK), fPtr->mmio_len))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "munmap mmio: %s\n", strerror(errno));
+ fPtr->mmio = NULL;
+ /* FIXME: restore var.accel_flags [geert] */
+ }
+ return TRUE;
+}
+
+/* -------------------------------------------------------------------- */
+
+Bool
+fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ pScrn->vtSema = TRUE;
+
+ /* set */
+ if (!fbdevHWSetMode(pScrn, mode, FALSE))
+ return FALSE;
+
+ /* read back */
+ if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOGET_FSCREENINFO: %s\n", strerror(errno));
+ return FALSE;
+ }
+ if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOGET_VSCREENINFO: %s\n", strerror(errno));
+ return FALSE;
+ }
+
+ if (pScrn->defaultVisual == TrueColor ||
+ pScrn->defaultVisual == DirectColor) {
+ /* XXX: This is a hack, but it should be a NOP for all the setups that
+ * worked before and actually seems to fix some others...
+ */
+ pScrn->offset.red = fPtr->var.red.offset;
+ pScrn->offset.green = fPtr->var.green.offset;
+ pScrn->offset.blue = fPtr->var.blue.offset;
+ pScrn->mask.red = ((1 << fPtr->var.red.length) - 1) << fPtr->var.red.offset;
+ pScrn->mask.green = ((1 << fPtr->var.green.length) - 1) << fPtr->var.green.offset;
+ pScrn->mask.blue = ((1 << fPtr->var.blue.length) - 1) << fPtr->var.blue.offset;
+ }
+
+ return TRUE;
+}
+
+/* -------------------------------------------------------------------- */
+/* video mode save/restore */
+void
+fbdevHWSave(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->saved_var)))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOGET_VSCREENINFO: %s\n", strerror(errno));
+}
+
+void
+fbdevHWRestore(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->saved_var)))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+}
+
+/* -------------------------------------------------------------------- */
+/* callback for xf86HandleColormaps */
+
+void
+fbdevHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ struct fb_cmap cmap;
+ unsigned short red,green,blue;
+ int i;
+
+ cmap.len = 1;
+ cmap.red = &red;
+ cmap.green = &green;
+ cmap.blue = &blue;
+ cmap.transp = NULL;
+ for (i = 0; i < numColors; i++) {
+ cmap.start = indices[i];
+ red = (colors[indices[i]].red << 8) |
+ colors[indices[i]].red;
+ green = (colors[indices[i]].green << 8) |
+ colors[indices[i]].green;
+ blue = (colors[indices[i]].blue << 8) |
+ colors[indices[i]].blue;
+ if (-1 == ioctl(fPtr->fd,FBIOPUTCMAP,(void*)&cmap))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOPUTCMAP: %s\n", strerror(errno));
+ }
+}
+
+/* -------------------------------------------------------------------- */
+/* these can be hooked directly into ScrnInfoRec */
+
+ModeStatus
+fbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ if (!fbdevHWSetMode(pScrn, mode, TRUE))
+ return MODE_BAD;
+
+ return MODE_OK;
+}
+
+Bool
+fbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+
+ if (!fbdevHWSetMode(pScrn, mode, FALSE))
+ return FALSE;
+
+ return TRUE;
+}
+
+void
+fbdevHWAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ if ( x < 0 || x + fPtr->var.xres > fPtr->var.xres_virtual ||
+ y < 0 || y + fPtr->var.yres > fPtr->var.yres_virtual )
+ return;
+
+ fPtr->var.xoffset = x;
+ fPtr->var.yoffset = y;
+ if (-1 == ioctl(fPtr->fd,FBIOPAN_DISPLAY,(void*)&fPtr->var))
+ xf86DrvMsgVerb(scrnIndex, X_WARNING, 5,
+ "FBIOPAN_DISPLAY: %s\n", strerror(errno));
+}
+
+Bool
+fbdevHWEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ fbdevHWAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ return TRUE;
+}
+
+void
+fbdevHWLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ fbdevHWRestore(pScrn);
+}
+
+void
+fbdevHWDPMSSet(ScrnInfoPtr pScrn, int mode, int flags)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ unsigned long fbmode;
+
+ if (!pScrn->vtSema)
+ return;
+
+ switch (mode) {
+ case DPMSModeOn:
+ fbmode = 0;
+ break;
+ case DPMSModeStandby:
+ fbmode = 2;
+ break;
+ case DPMSModeSuspend:
+ fbmode = 3;
+ break;
+ case DPMSModeOff:
+ fbmode = 4;
+ break;
+ default:
+ return;
+ }
+
+ if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *)fbmode))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOBLANK: %s\n", strerror(errno));
+}
+
+Bool
+fbdevHWSaveScreen(ScreenPtr pScreen, int mode)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ unsigned long unblank;
+
+ if (!pScrn->vtSema)
+ return TRUE;
+
+ unblank = xf86IsUnblank(mode);
+
+ if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *)(1-unblank))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOBLANK: %s\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+xf86SwitchModeProc *
+fbdevHWSwitchModeWeak(void) { return fbdevHWSwitchMode; }
+
+xf86AdjustFrameProc *
+fbdevHWAdjustFrameWeak(void) { return fbdevHWAdjustFrame; }
+
+xf86EnterVTProc *
+fbdevHWEnterVTWeak(void) { return fbdevHWEnterVT; }
+
+xf86LeaveVTProc *
+fbdevHWLeaveVTWeak(void) { return fbdevHWLeaveVT; }
+
+xf86ValidModeProc *
+fbdevHWValidModeWeak(void) { return fbdevHWValidMode; }
+
+xf86DPMSSetProc *
+fbdevHWDPMSSetWeak(void) { return fbdevHWDPMSSet; }
+
+xf86LoadPaletteProc *
+fbdevHWLoadPaletteWeak(void) { return fbdevHWLoadPalette; }
+
+SaveScreenProcPtr
+fbdevHWSaveScreenWeak(void) { return fbdevHWSaveScreen; }
diff --git a/xorg-server/hw/xfree86/loader/Makefile.am b/xorg-server/hw/xfree86/loader/Makefile.am
index 0e5b304a4..9cb27a2bd 100644
--- a/xorg-server/hw/xfree86/loader/Makefile.am
+++ b/xorg-server/hw/xfree86/loader/Makefile.am
@@ -1,33 +1,33 @@
-noinst_LTLIBRARIES = libloader.la
-
-INCLUDES = $(XORG_INCS) -I$(srcdir)/../parser -I$(top_srcdir)/miext/cw \
- -I$(srcdir)/../ddc -I$(srcdir)/../i2c -I$(srcdir)/../modes \
- -I$(srcdir)/../ramdac
-
-#AM_LDFLAGS = -r
-AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
-
-EXTRA_DIST = \
- loader.h \
- loaderProcs.h \
- sdksyms.sh
-
-nodist_libloader_la_SOURCES = \
- sdksyms.c
-
-libloader_la_SOURCES = \
- loader.c \
- loaderProcs.h \
- loadext.c \
- loadmod.c \
- os.c
-
-libloader_la_LIBADD = $(DLOPEN_LIBS)
-
-CLEANFILES = sdksyms.c sdksyms.dep
-
-sdksyms.dep sdksyms.c: sdksyms.sh $(top_builddir)/include/do-not-use-config.h
- CPP='$(CPP)' AWK='$(AWK)' $(srcdir)/sdksyms.sh $(top_srcdir) $(AM_CFLAGS) $(CFLAGS) $(INCLUDES)
-
-SDKSYMS_DEP = sdksyms.dep
-include $(SDKSYMS_DEP)
+noinst_LTLIBRARIES = libloader.la
+
+INCLUDES = $(XORG_INCS) -I$(srcdir)/../parser -I$(top_srcdir)/miext/cw \
+ -I$(srcdir)/../ddc -I$(srcdir)/../i2c -I$(srcdir)/../modes \
+ -I$(srcdir)/../ramdac
+
+#AM_LDFLAGS = -r
+AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
+
+EXTRA_DIST = \
+ loader.h \
+ loaderProcs.h \
+ sdksyms.sh
+
+nodist_libloader_la_SOURCES = \
+ sdksyms.c
+
+libloader_la_SOURCES = \
+ loader.c \
+ loaderProcs.h \
+ loadext.c \
+ loadmod.c \
+ os.c
+
+libloader_la_LIBADD = $(DLOPEN_LIBS)
+
+CLEANFILES = sdksyms.c sdksyms.dep
+
+sdksyms.dep sdksyms.c: sdksyms.sh $(top_builddir)/include/do-not-use-config.h
+ CPP='$(CPP)' AWK='$(AWK)' $(srcdir)/sdksyms.sh $(top_srcdir) $(AM_CFLAGS) $(CFLAGS) $(INCLUDES)
+
+SDKSYMS_DEP = sdksyms.dep
+include $(SDKSYMS_DEP)
diff --git a/xorg-server/hw/xfree86/loader/loadmod.c b/xorg-server/hw/xfree86/loader/loadmod.c
index 9f820993a..cf231c1f0 100644
--- a/xorg-server/hw/xfree86/loader/loadmod.c
+++ b/xorg-server/hw/xfree86/loader/loadmod.c
@@ -1,1253 +1,1253 @@
-/*
- * Copyright 1995-1998 by Metro Link, 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 name of Metro Link, Inc. not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Metro Link, Inc. makes no
- * representations about the suitability of this software for any purpose.
- * It is provided "as is" without express or implied warranty.
- *
- * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL METRO LINK, INC. 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) 1997-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).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "os.h"
-/* For stat() and related stuff */
-#define NO_OSLIB_PROTOTYPES
-#include "xf86_OSlib.h"
-#define LOADERDECLARATIONS
-#include "loaderProcs.h"
-#include "misc.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86Xinput.h"
-#include "loader.h"
-#include "xf86Optrec.h"
-
-#include <sys/types.h>
-#include <regex.h>
-#include <dirent.h>
-#include <limits.h>
-
-typedef struct _pattern {
- const char *pattern;
- regex_t rex;
-} PatternRec, *PatternPtr;
-
-/* Prototypes for static functions */
-static char *FindModule(const char *, const char *, const char **,
- PatternPtr);
-static Bool CheckVersion(const char *, XF86ModuleVersionInfo *,
- const XF86ModReqInfo *);
-static void UnloadModuleOrDriver(ModuleDescPtr mod);
-static char *LoaderGetCanonicalName(const char *, PatternPtr);
-static void RemoveChild(ModuleDescPtr);
-static ModuleDescPtr doLoadModule(const char *, const char *, const char **,
- const char **, pointer,
- const XF86ModReqInfo *, int *, int *);
-
-const ModuleVersions LoaderVersionInfo = {
- XORG_VERSION_CURRENT,
- ABI_ANSIC_VERSION,
- ABI_VIDEODRV_VERSION,
- ABI_XINPUT_VERSION,
- ABI_EXTENSION_VERSION,
- ABI_FONT_VERSION
-};
-
-static void
-FreeStringList(char **paths)
-{
- char **p;
-
- if (!paths)
- return;
-
- for (p = paths; *p; p++)
- free(*p);
-
- free(paths);
-}
-
-static char **defaultPathList = NULL;
-
-static Bool
-PathIsAbsolute(const char *path)
-{
- return *path == '/';
-}
-
-/*
- * Convert a comma-separated path into a NULL-terminated array of path
- * elements, rejecting any that are not full absolute paths, and appending
- * a '/' when it isn't already present.
- */
-static char **
-InitPathList(const char *path)
-{
- char *fullpath = NULL;
- char *elem = NULL;
- char **list = NULL, **save = NULL;
- int len;
- int addslash;
- int n = 0;
-
- if (!path)
- return defaultPathList;
-
- fullpath = strdup(path);
- if (!fullpath)
- return NULL;
- elem = strtok(fullpath, ",");
- while (elem) {
- if (PathIsAbsolute(elem))
- {
- len = strlen(elem);
- addslash = (elem[len - 1] != '/');
- if (addslash)
- len++;
- save = list;
- list = realloc(list, (n + 2) * sizeof(char *));
- if (!list) {
- if (save) {
- save[n] = NULL;
- FreeStringList(save);
- }
- free(fullpath);
- return NULL;
- }
- list[n] = malloc(len + 1);
- if (!list[n]) {
- FreeStringList(list);
- free(fullpath);
- return NULL;
- }
- strcpy(list[n], elem);
- if (addslash) {
- list[n][len - 1] = '/';
- list[n][len] = '\0';
- }
- n++;
- }
- elem = strtok(NULL, ",");
- }
- if (list)
- list[n] = NULL;
- free(fullpath);
- return list;
-}
-
-static void
-FreePathList(char **pathlist)
-{
- if (pathlist && pathlist != defaultPathList)
- FreeStringList(pathlist);
-}
-
-void
-LoaderSetPath(const char *path)
-{
- if (!path)
- return;
-
- defaultPathList = InitPathList(path);
-}
-
-/* Standard set of module subdirectories to search, in order of preference */
-static const char *stdSubdirs[] = {
- "",
- "input/",
- "drivers/",
- "multimedia/",
- "extensions/",
- "internal/",
- NULL
-};
-
-/*
- * Standard set of module name patterns to check, in order of preference
- * These are regular expressions (suitable for use with POSIX regex(3)).
- *
- * This list assumes that you're an ELFish platform and therefore your
- * shared libraries are named something.so. If we're ever nuts enough
- * to port this DDX to, say, Darwin, we'll need to fix this.
- */
-static PatternRec stdPatterns[] = {
- {"^lib(.*)\\.so$",},
- {"(.*)_drv\\.so$",},
- {"(.*)\\.so$",},
- {NULL,}
-};
-
-static PatternPtr
-InitPatterns(const char **patternlist)
-{
- char errmsg[80];
- int i, e;
- PatternPtr patterns = NULL;
- PatternPtr p = NULL;
- static int firstTime = 1;
- const char **s;
-
- if (firstTime) {
- /* precompile stdPatterns */
- firstTime = 0;
- for (p = stdPatterns; p->pattern; p++)
- if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) {
- regerror(e, &p->rex, errmsg, sizeof(errmsg));
- FatalError("InitPatterns: regcomp error for `%s': %s\n",
- p->pattern, errmsg);
- }
- }
-
- if (patternlist) {
- for (i = 0, s = patternlist; *s; i++, s++)
- if (*s == DEFAULT_LIST)
- i += sizeof(stdPatterns) / sizeof(stdPatterns[0]) - 1 - 1;
- patterns = malloc((i + 1) * sizeof(PatternRec));
- if (!patterns) {
- return NULL;
- }
- for (i = 0, s = patternlist; *s; i++, s++)
- if (*s != DEFAULT_LIST) {
- p = patterns + i;
- p->pattern = *s;
- if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) {
- regerror(e, &p->rex, errmsg, sizeof(errmsg));
- ErrorF("InitPatterns: regcomp error for `%s': %s\n",
- p->pattern, errmsg);
- i--;
- }
- } else {
- for (p = stdPatterns; p->pattern; p++, i++)
- patterns[i] = *p;
- if (p != stdPatterns)
- i--;
- }
- patterns[i].pattern = NULL;
- } else
- patterns = stdPatterns;
- return patterns;
-}
-
-static void
-FreePatterns(PatternPtr patterns)
-{
- if (patterns && patterns != stdPatterns)
- free(patterns);
-}
-
-static const char **
-InitSubdirs(const char **subdirlist)
-{
- int i;
- const char **tmp_subdirlist = NULL;
- char **subdirs = NULL;
- const char **s, **stmp = NULL;
- const char *osname;
- const char *slash;
- int oslen = 0, len;
- Bool indefault;
-
- if (subdirlist == NULL) {
- subdirlist = tmp_subdirlist = malloc(2 * sizeof(char *));
- if (subdirlist == NULL)
- return NULL;
- subdirlist[0] = DEFAULT_LIST;
- subdirlist[1] = NULL;
- }
-
- LoaderGetOS(&osname, NULL, NULL, NULL);
- oslen = strlen(osname);
-
- {
- /* Count number of entries and check for invalid paths */
- for (i = 0, s = subdirlist; *s; i++, s++) {
- if (*s == DEFAULT_LIST) {
- i += sizeof(stdSubdirs) / sizeof(stdSubdirs[0]) - 1 - 1;
- } else {
- /*
- * Path validity check. Don't allow absolute paths, or
- * paths containing "..". To catch absolute paths on
- * platforms that use driver letters, don't allow the ':'
- * character to appear at all.
- */
- if (**s == '/' || **s == '\\' || strchr(*s, ':') ||
- strstr(*s, "..")) {
- xf86Msg(X_ERROR, "InitSubdirs: Bad subdir: \"%s\"\n", *s);
- free(tmp_subdirlist);
- return NULL;
- }
- }
- }
- subdirs = malloc((i * 2 + 1) * sizeof(char *));
- if (!subdirs) {
- free(tmp_subdirlist);
- return NULL;
- }
- i = 0;
- s = subdirlist;
- indefault = FALSE;
- while (*s) {
- if (*s == DEFAULT_LIST) {
- /* Divert to the default list */
- indefault = TRUE;
- stmp = ++s;
- s = stdSubdirs;
- }
- len = strlen(*s);
- if (**s && (*s)[len - 1] != '/') {
- slash = "/";
- len++;
- } else
- slash = "";
- len += oslen + 2;
- if (!(subdirs[i] = malloc(len))) {
- while (--i >= 0)
- free(subdirs[i]);
- free(subdirs);
- free(tmp_subdirlist);
- return NULL;
- }
- /* tack on the OS name */
- sprintf(subdirs[i], "%s%s%s/", *s, slash, osname);
- i++;
- /* path as given */
- subdirs[i] = strdup(*s);
- i++;
- s++;
- if (indefault && !s) {
- /* revert back to the main list */
- indefault = FALSE;
- s = stmp;
- }
- }
- subdirs[i] = NULL;
- }
- free(tmp_subdirlist);
- return (const char **)subdirs;
-}
-
-static void
-FreeSubdirs(const char **subdirs)
-{
- const char **s;
-
- if (subdirs) {
- for (s = subdirs; *s; s++)
- free((char *)*s);
- free(subdirs);
- }
-}
-
-static char *
-FindModuleInSubdir(const char *dirpath, const char *module)
-{
- struct dirent *direntry = NULL;
- DIR *dir = NULL;
- char *ret = NULL, tmpBuf[PATH_MAX];
- struct stat stat_buf;
-
- dir = opendir(dirpath);
- if (!dir)
- return NULL;
-
- while ((direntry = readdir(dir))) {
- if (direntry->d_name[0] == '.')
- continue;
- snprintf(tmpBuf, PATH_MAX, "%s%s/", dirpath, direntry->d_name);
- /* the stat with the appended / fails for normal files,
- and works for sub dirs fine, looks a bit strange in strace
- but does seem to work */
- if ((stat(tmpBuf, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)) {
- if ((ret = FindModuleInSubdir(tmpBuf, module)))
- break;
- continue;
- }
-
- snprintf(tmpBuf, PATH_MAX, "lib%s.so", module);
- if (strcmp(direntry->d_name, tmpBuf) == 0) {
- if (asprintf(&ret, "%s%s", dirpath, tmpBuf) == -1)
- ret = NULL;
- break;
- }
-
- snprintf(tmpBuf, PATH_MAX, "%s_drv.so", module);
- if (strcmp(direntry->d_name, tmpBuf) == 0) {
- if (asprintf(&ret, "%s%s", dirpath, tmpBuf) == -1)
- ret = NULL;
- break;
- }
-
- snprintf(tmpBuf, PATH_MAX, "%s.so", module);
- if (strcmp(direntry->d_name, tmpBuf) == 0) {
- if (asprintf(&ret, "%s%s", dirpath, tmpBuf) == -1)
- ret = NULL;
- break;
- }
- }
-
- closedir(dir);
- return ret;
-}
-
-static char *
-FindModule(const char *module, const char *dirname, const char **subdirlist,
- PatternPtr patterns)
-{
- char buf[PATH_MAX + 1];
- char *dirpath = NULL;
- char *name = NULL;
- int dirlen;
- const char **subdirs = NULL;
- const char **s;
-
- dirpath = (char *)dirname;
- if (strlen(dirpath) > PATH_MAX)
- return NULL;
-
- subdirs = InitSubdirs(subdirlist);
- if (!subdirs)
- return NULL;
-
- for (s = subdirs; *s; s++) {
- if ((dirlen = strlen(dirpath) + strlen(*s)) > PATH_MAX)
- continue;
- strcpy(buf, dirpath);
- strcat(buf, *s);
- if ((name = FindModuleInSubdir(buf, module)))
- break;
- }
-
- FreeSubdirs(subdirs);
- if (dirpath != dirname)
- free(dirpath);
-
- return name;
-}
-
-char **
-LoaderListDirs(const char **subdirlist, const char **patternlist)
-{
- char buf[PATH_MAX + 1];
- char **pathlist;
- char **elem;
- const char **subdirs;
- const char **s;
- PatternPtr patterns;
- PatternPtr p;
- DIR *d;
- struct dirent *dp;
- regmatch_t match[2];
- struct stat stat_buf;
- int len, dirlen;
- char *fp;
- char **listing = NULL;
- char **save;
- char **ret = NULL;
- int n = 0;
-
- if (!(pathlist = InitPathList(NULL)))
- return NULL;
- if (!(subdirs = InitSubdirs(subdirlist)))
- goto bail;
- if (!(patterns = InitPatterns(patternlist)))
- goto bail;
-
- for (elem = pathlist; *elem; elem++) {
- for (s = subdirs; *s; s++) {
- if ((dirlen = strlen(*elem) + strlen(*s)) > PATH_MAX)
- continue;
- strcpy(buf, *elem);
- strcat(buf, *s);
- fp = buf + dirlen;
- if (stat(buf, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode) &&
- (d = opendir(buf))) {
- if (buf[dirlen - 1] != '/') {
- buf[dirlen++] = '/';
- fp++;
- }
- while ((dp = readdir(d))) {
- if (dirlen + strlen(dp->d_name) > PATH_MAX)
- continue;
- strcpy(fp, dp->d_name);
- if (!(stat(buf, &stat_buf) == 0 &&
- S_ISREG(stat_buf.st_mode)))
- continue;
- for (p = patterns; p->pattern; p++) {
- if (regexec(&p->rex, dp->d_name, 2, match, 0) == 0 &&
- match[1].rm_so != -1) {
- len = match[1].rm_eo - match[1].rm_so;
- save = listing;
- listing = realloc(listing,
- (n + 2) * sizeof(char *));
- if (!listing) {
- if (save) {
- save[n] = NULL;
- FreeStringList(save);
- }
- closedir(d);
- goto bail;
- }
- listing[n] = malloc(len + 1);
- if (!listing[n]) {
- FreeStringList(listing);
- closedir(d);
- goto bail;
- }
- strncpy(listing[n], dp->d_name + match[1].rm_so,
- len);
- listing[n][len] = '\0';
- n++;
- break;
- }
- }
- }
- closedir(d);
- }
- }
- }
- if (listing)
- listing[n] = NULL;
- ret = listing;
-
-bail:
- FreePatterns(patterns);
- FreeSubdirs(subdirs);
- FreePathList(pathlist);
- return ret;
-}
-
-void
-LoaderFreeDirList(char **list)
-{
- FreeStringList(list);
-}
-
-static Bool
-CheckVersion(const char *module, XF86ModuleVersionInfo * data,
- const XF86ModReqInfo * req)
-{
- int vercode[4];
- char verstr[4];
- long ver = data->xf86version;
- MessageType errtype;
-
- xf86Msg(X_INFO, "Module %s: vendor=\"%s\"\n",
- data->modname ? data->modname : "UNKNOWN!",
- data->vendor ? data->vendor : "UNKNOWN!");
-
- /* Check for the different scheme used in XFree86 4.0.x releases:
- * ((((((((major << 7) | minor) << 7) | subminor) << 5) | beta) << 5) | alpha)
- * Since it wasn't used in 4.1.0 or later, limit to versions in the 4.0.x
- * range, which limits the overlap with the new version scheme to conflicts
- * with 6.71.8.764 through 6.72.39.934.
- */
- if ((ver > (4 << 24)) && (ver < ( (4 << 24) + (1 << 17)))) {
- /* 4.0.x and earlier */
- verstr[1] = verstr[3] = 0;
- verstr[2] = (ver & 0x1f) ? (ver & 0x1f) + 'a' - 1 : 0;
- ver >>= 5;
- verstr[0] = (ver & 0x1f) ? (ver & 0x1f) + 'A' - 1 : 0;
- ver >>= 5;
- vercode[2] = ver & 0x7f;
- ver >>= 7;
- vercode[1] = ver & 0x7f;
- ver >>= 7;
- vercode[0] = ver;
- xf86ErrorF("\tcompiled for %d.%d", vercode[0], vercode[1]);
- if (vercode[2] != 0)
- xf86ErrorF(".%d", vercode[2]);
- xf86ErrorF("%s%s, module version = %d.%d.%d\n", verstr, verstr + 2,
- data->majorversion, data->minorversion, data->patchlevel);
- } else {
- vercode[0] = ver / 10000000;
- vercode[1] = (ver / 100000) % 100;
- vercode[2] = (ver / 1000) % 100;
- vercode[3] = ver % 1000;
- xf86ErrorF("\tcompiled for %d.%d.%d", vercode[0], vercode[1],
- vercode[2]);
- if (vercode[3] != 0)
- xf86ErrorF(".%d", vercode[3]);
- xf86ErrorF(", module version = %d.%d.%d\n", data->majorversion,
- data->minorversion, data->patchlevel);
- }
-
- if (data->moduleclass)
- xf86ErrorFVerb(2, "\tModule class: %s\n", data->moduleclass);
-
- ver = -1;
- if (data->abiclass) {
- int abimaj, abimin;
- int vermaj, vermin;
-
- if (!strcmp(data->abiclass, ABI_CLASS_ANSIC))
- ver = LoaderVersionInfo.ansicVersion;
- else if (!strcmp(data->abiclass, ABI_CLASS_VIDEODRV))
- ver = LoaderVersionInfo.videodrvVersion;
- else if (!strcmp(data->abiclass, ABI_CLASS_XINPUT))
- ver = LoaderVersionInfo.xinputVersion;
- else if (!strcmp(data->abiclass, ABI_CLASS_EXTENSION))
- ver = LoaderVersionInfo.extensionVersion;
- else if (!strcmp(data->abiclass, ABI_CLASS_FONT))
- ver = LoaderVersionInfo.fontVersion;
-
- abimaj = GET_ABI_MAJOR(data->abiversion);
- abimin = GET_ABI_MINOR(data->abiversion);
- xf86ErrorFVerb(2, "\tABI class: %s, version %d.%d\n",
- data->abiclass, abimaj, abimin);
- if (ver != -1) {
- vermaj = GET_ABI_MAJOR(ver);
- vermin = GET_ABI_MINOR(ver);
- if (abimaj != vermaj) {
- if (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL)
- errtype = X_WARNING;
- else
- errtype = X_ERROR;
- xf86MsgVerb(errtype, 0,
- "module ABI major version (%d) doesn't"
- " match the server's version (%d)\n",
- abimaj, vermaj);
- if (!(LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL))
- return FALSE;
- } else if (abimin > vermin) {
- if (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL)
- errtype = X_WARNING;
- else
- errtype = X_ERROR;
- xf86MsgVerb(errtype, 0,
- "module ABI minor version (%d) is "
- "newer than the server's version "
- "(%d)\n", abimin, vermin);
- if (!(LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL))
- return FALSE;
- }
- }
- }
-
- /* Check against requirements that the caller has specified */
- if (req) {
- if (req->majorversion != MAJOR_UNSPEC) {
- if (data->majorversion != req->majorversion) {
- xf86MsgVerb(X_WARNING, 2, "module major version (%d) "
- "doesn't match required major version (%d)\n",
- data->majorversion, req->majorversion);
- return FALSE;
- } else if (req->minorversion != MINOR_UNSPEC) {
- if (data->minorversion < req->minorversion) {
- xf86MsgVerb(X_WARNING, 2, "module minor version (%d) "
- "is less than the required minor version (%d)\n",
- data->minorversion, req->minorversion);
- return FALSE;
- } else if (data->minorversion == req->minorversion &&
- req->patchlevel != PATCH_UNSPEC) {
- if (data->patchlevel < req->patchlevel) {
- xf86MsgVerb(X_WARNING, 2, "module patch level (%d) "
- "is less than the required patch level (%d)\n",
- data->patchlevel, req->patchlevel);
- return FALSE;
- }
- }
- }
- }
- if (req->moduleclass) {
- if (!data->moduleclass ||
- strcmp(req->moduleclass, data->moduleclass)) {
- xf86MsgVerb(X_WARNING, 2, "Module class (%s) doesn't match "
- "the required class (%s)\n",
- data->moduleclass ? data->moduleclass : "<NONE>",
- req->moduleclass);
- return FALSE;
- }
- } else if (req->abiclass != ABI_CLASS_NONE) {
- if (!data->abiclass || strcmp(req->abiclass, data->abiclass)) {
- xf86MsgVerb(X_WARNING, 2, "ABI class (%s) doesn't match the "
- "required ABI class (%s)\n",
- data->abiclass ? data->abiclass : "<NONE>",
- req->abiclass);
- return FALSE;
- }
- }
- if ((req->abiclass != ABI_CLASS_NONE) &&
- req->abiversion != ABI_VERS_UNSPEC) {
- int reqmaj, reqmin, maj, min;
-
- reqmaj = GET_ABI_MAJOR(req->abiversion);
- reqmin = GET_ABI_MINOR(req->abiversion);
- maj = GET_ABI_MAJOR(data->abiversion);
- min = GET_ABI_MINOR(data->abiversion);
- if (maj != reqmaj) {
- xf86MsgVerb(X_WARNING, 2, "ABI major version (%d) doesn't "
- "match the required ABI major version (%d)\n",
- maj, reqmaj);
- return FALSE;
- }
- /* XXX Maybe this should be the other way around? */
- if (min > reqmin) {
- xf86MsgVerb(X_WARNING, 2, "module ABI minor version (%d) "
- "is newer than that available (%d)\n", min, reqmin);
- return FALSE;
- }
- }
- }
- return TRUE;
-}
-
-static ModuleDescPtr
-AddSibling(ModuleDescPtr head, ModuleDescPtr new)
-{
- new->sib = head;
- return new;
-}
-
-pointer
-LoadSubModule(pointer _parent, const char *module,
- const char **subdirlist, const char **patternlist,
- pointer options, const XF86ModReqInfo * modreq,
- int *errmaj, int *errmin)
-{
- ModuleDescPtr submod;
- ModuleDescPtr parent = (ModuleDescPtr)_parent;
-
- xf86MsgVerb(X_INFO, 3, "Loading sub module \"%s\"\n", module);
-
- if (PathIsAbsolute(module)) {
- xf86Msg(X_ERROR,
- "LoadSubModule: Absolute module path not permitted: \"%s\"\n",
- module);
- if (errmaj)
- *errmaj = LDR_BADUSAGE;
- if (errmin)
- *errmin = 0;
- return NULL;
- }
-
- submod = doLoadModule(module, NULL, subdirlist, patternlist, options,
- modreq, errmaj, errmin);
- if (submod && submod != (ModuleDescPtr) 1) {
- parent->child = AddSibling(parent->child, submod);
- submod->parent = parent;
- }
- return submod;
-}
-
-static ModuleDescPtr
-NewModuleDesc(const char *name)
-{
- ModuleDescPtr mdp = calloc(1, sizeof(ModuleDesc));
-
- if (mdp)
- mdp->name = xstrdup(name);
-
- return mdp;
-}
-
-ModuleDescPtr
-DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent)
-{
- ModuleDescPtr ret;
- int errmaj, errmin;
-
- if (!mod)
- return NULL;
-
- ret = NewModuleDesc(mod->name);
- if (ret == NULL)
- return NULL;
-
- if (!(ret->handle = LoaderOpen(mod->path, &errmaj, &errmin))) {
- free(ret);
- return NULL;
- }
-
- ret->SetupProc = mod->SetupProc;
- ret->TearDownProc = mod->TearDownProc;
- ret->TearDownData = NULL;
- ret->child = DuplicateModule(mod->child, ret);
- ret->sib = DuplicateModule(mod->sib, parent);
- ret->parent = parent;
- ret->VersionInfo = mod->VersionInfo;
- ret->path = strdup(mod->path);
-
- return ret;
-}
-
-static const char *compiled_in_modules[] = {
- "ddc",
- "i2c",
- "ramdac",
- NULL
-};
-
-static ModuleDescPtr
-doLoadModule(const char *module, const char *path, const char **subdirlist,
- const char **patternlist, pointer options,
- const XF86ModReqInfo * modreq,
- int *errmaj, int *errmin)
-{
- XF86ModuleData *initdata = NULL;
- char **pathlist = NULL;
- char *found = NULL;
- char *name = NULL;
- char **path_elem = NULL;
- char *p = NULL;
- ModuleDescPtr ret = NULL;
- PatternPtr patterns = NULL;
- int noncanonical = 0;
- char *m = NULL;
- const char **cim;
-
- xf86MsgVerb(X_INFO, 3, "LoadModule: \"%s\"", module);
-
- patterns = InitPatterns(patternlist);
- name = LoaderGetCanonicalName(module, patterns);
- noncanonical = (name && strcmp(module, name) != 0);
- if (noncanonical) {
- xf86ErrorFVerb(3, " (%s)\n", name);
- xf86MsgVerb(X_WARNING, 1,
- "LoadModule: given non-canonical module name \"%s\"\n",
- module);
- m = name;
- } else {
- xf86ErrorFVerb(3, "\n");
- m = (char *)module;
- }
-
- for (cim = compiled_in_modules; *cim; cim++)
- if (!strcmp (m, *cim))
- {
- xf86MsgVerb(X_INFO, 3, "Module \"%s\" already built-in\n", m);
- ret = (ModuleDescPtr) 1;
- goto LoadModule_exit;
- }
-
- if (!name) {
- if (errmaj)
- *errmaj = LDR_BADUSAGE;
- if (errmin)
- *errmin = 0;
- goto LoadModule_fail;
- }
- ret = NewModuleDesc(name);
- if (!ret) {
- if (errmaj)
- *errmaj = LDR_NOMEM;
- if (errmin)
- *errmin = 0;
- goto LoadModule_fail;
- }
-
- pathlist = InitPathList(path);
- if (!pathlist) {
- /* This could be a malloc failure too */
- if (errmaj)
- *errmaj = LDR_BADUSAGE;
- if (errmin)
- *errmin = 1;
- goto LoadModule_fail;
- }
-
- /*
- * if the module name is not a full pathname, we need to
- * check the elements in the path
- */
- if (PathIsAbsolute(module))
- found = xstrdup(module);
- path_elem = pathlist;
- while (!found && *path_elem != NULL) {
- found = FindModule(m, *path_elem, subdirlist, patterns);
- path_elem++;
- /*
- * When the module name isn't the canonical name, search for the
- * former if no match was found for the latter.
- */
- if (!*path_elem && m == name) {
- path_elem = pathlist;
- m = (char *)module;
- }
- }
-
- /*
- * did we find the module?
- */
- if (!found) {
- xf86Msg(X_WARNING, "Warning, couldn't open module %s\n", module);
- if (errmaj)
- *errmaj = LDR_NOENT;
- if (errmin)
- *errmin = 0;
- goto LoadModule_fail;
- }
- ret->handle = LoaderOpen(found, errmaj, errmin);
- if (ret->handle < 0)
- goto LoadModule_fail;
- ret->path = strdup(found);
-
- /* drop any explicit suffix from the module name */
- p = strchr(name, '.');
- if (p)
- *p = '\0';
-
- /*
- * now check if the special data object <modulename>ModuleData is
- * present.
- */
- if (asprintf(&p, "%sModuleData", name) == -1) {
- p = NULL;
- if (errmaj)
- *errmaj = LDR_NOMEM;
- if (errmin)
- *errmin = 0;
- goto LoadModule_fail;
- }
- initdata = LoaderSymbol(p);
- if (initdata) {
- ModuleSetupProc setup;
- ModuleTearDownProc teardown;
- XF86ModuleVersionInfo *vers;
-
- vers = initdata->vers;
- setup = initdata->setup;
- teardown = initdata->teardown;
-
- if (vers) {
- if (!CheckVersion(module, vers, modreq)) {
- if (errmaj)
- *errmaj = LDR_MISMATCH;
- if (errmin)
- *errmin = 0;
- goto LoadModule_fail;
- }
- } else {
- xf86Msg(X_ERROR,
- "LoadModule: Module %s does not supply"
- " version information\n", module);
- if (errmaj)
- *errmaj = LDR_INVALID;
- if (errmin)
- *errmin = 0;
- goto LoadModule_fail;
- }
- if (setup)
- ret->SetupProc = setup;
- if (teardown)
- ret->TearDownProc = teardown;
- ret->VersionInfo = vers;
- } else {
- /* No initdata is OK for external modules */
- if (options == EXTERN_MODULE)
- goto LoadModule_exit;
-
- /* no initdata, fail the load */
- xf86Msg(X_ERROR, "LoadModule: Module %s does not have a %s "
- "data object.\n", module, p);
- if (errmaj)
- *errmaj = LDR_INVALID;
- if (errmin)
- *errmin = 0;
- goto LoadModule_fail;
- }
- if (ret->SetupProc) {
- ret->TearDownData = ret->SetupProc(ret, options, errmaj, errmin);
- if (!ret->TearDownData) {
- goto LoadModule_fail;
- }
- } else if (options) {
- xf86Msg(X_WARNING, "Module Options present, but no SetupProc "
- "available for %s\n", module);
- }
- goto LoadModule_exit;
-
- LoadModule_fail:
- UnloadModule(ret);
- ret = NULL;
-
- LoadModule_exit:
- FreePathList(pathlist);
- FreePatterns(patterns);
- free(found);
- free(name);
- free(p);
-
- return ret;
-}
-
-/*
- * LoadModule: load a module
- *
- * module The module name. Normally this is not a filename but the
- * module's "canonical name. A full pathname is, however,
- * also accepted.
- * path A comma separated list of module directories.
- * subdirlist A NULL terminated list of subdirectories to search. When
- * NULL, the default "stdSubdirs" list is used. The default
- * list is also substituted for entries with value DEFAULT_LIST.
- * patternlist A NULL terminated list of regular expressions used to find
- * module filenames. Each regex should contain exactly one
- * subexpression that corresponds to the canonical module name.
- * When NULL, the default "stdPatterns" list is used. The
- * default list is also substituted for entries with value
- * DEFAULT_LIST.
- * options A NULL terminated list of Options that are passed to the
- * module's SetupProc function.
- * modreq An optional XF86ModReqInfo* containing
- * version/ABI/vendor-ABI requirements to check for when
- * loading the module. The following fields of the
- * XF86ModReqInfo struct are checked:
- * majorversion - must match the module's majorversion exactly
- * minorversion - the module's minorversion must be >= this
- * patchlevel - the module's minorversion.patchlevel must be
- * >= this. Patchlevel is ignored when
- * minorversion is not set.
- * abiclass - (string) must match the module's abiclass
- * abiversion - must be consistent with the module's
- * abiversion (major equal, minor no older)
- * moduleclass - string must match the module's moduleclass
- * string
- * "don't care" values are ~0 for numbers, and NULL for strings
- * errmaj Major error return.
- * errmin Minor error return.
- *
- */
-ModuleDescPtr
-LoadModule(const char *module, const char *path, const char **subdirlist,
- const char **patternlist, pointer options,
- const XF86ModReqInfo * modreq, int *errmaj, int *errmin)
-{
- return doLoadModule(module, path, subdirlist, patternlist, options,
- modreq, errmaj, errmin);
-}
-
-void
-UnloadModule(pointer mod)
-{
- UnloadModuleOrDriver((ModuleDescPtr)mod);
-}
-
-static void
-UnloadModuleOrDriver(ModuleDescPtr mod)
-{
- if (mod == (ModuleDescPtr) 1)
- return;
-
- if (mod == NULL || mod->name == NULL)
- return;
-
- xf86MsgVerb(X_INFO, 3, "UnloadModule: \"%s\"\n", mod->name);
-
- if ((mod->TearDownProc) && (mod->TearDownData))
- mod->TearDownProc(mod->TearDownData);
- LoaderUnload(mod->name, mod->handle);
-
- if (mod->child)
- UnloadModuleOrDriver(mod->child);
- if (mod->sib)
- UnloadModuleOrDriver(mod->sib);
- free(mod->path);
- free(mod->name);
- free(mod);
-}
-
-void
-UnloadSubModule(pointer _mod)
-{
- ModuleDescPtr mod = (ModuleDescPtr)_mod;
-
- if (mod == NULL || mod->name == NULL)
- return;
-
- xf86MsgVerb(X_INFO, 3, "UnloadSubModule: \"%s\"\n", mod->name);
-
- if ((mod->TearDownProc) && (mod->TearDownData))
- mod->TearDownProc(mod->TearDownData);
- LoaderUnload(mod->name, mod->handle);
-
- RemoveChild(mod);
-
- if (mod->child)
- UnloadModuleOrDriver(mod->child);
-
- free(mod->path);
- free(mod->name);
- free(mod);
-}
-
-static void
-RemoveChild(ModuleDescPtr child)
-{
- ModuleDescPtr mdp;
- ModuleDescPtr prevsib;
- ModuleDescPtr parent;
-
- if (!child->parent)
- return;
-
- parent = child->parent;
- if (parent->child == child) {
- parent->child = child->sib;
- return;
- }
-
- prevsib = parent->child;
- mdp = prevsib->sib;
- while (mdp && mdp != child) {
- prevsib = mdp;
- mdp = mdp->sib;
- }
- if (mdp == child)
- prevsib->sib = child->sib;
- return;
-}
-
-void
-LoaderErrorMsg(const char *name, const char *modname, int errmaj, int errmin)
-{
- const char *msg;
- MessageType type = X_ERROR;
-
- switch (errmaj) {
- case LDR_NOERROR:
- msg = "no error";
- break;
- case LDR_NOMEM:
- msg = "out of memory";
- break;
- case LDR_NOENT:
- msg = "module does not exist";
- break;
- case LDR_NOSUBENT:
- msg = "a required submodule could not be loaded";
- break;
- case LDR_NOSPACE:
- msg = "too many modules";
- break;
- case LDR_NOMODOPEN:
- msg = "open failed";
- break;
- case LDR_UNKTYPE:
- msg = "unknown module type";
- break;
- case LDR_NOLOAD:
- msg = "loader failed";
- break;
- case LDR_ONCEONLY:
- msg = "already loaded";
- type = X_INFO;
- break;
- case LDR_NOPORTOPEN:
- msg = "port open failed";
- break;
- case LDR_NOHARDWARE:
- msg = "no hardware found";
- break;
- case LDR_MISMATCH:
- msg = "module requirement mismatch";
- break;
- case LDR_BADUSAGE:
- msg = "invalid argument(s) to LoadModule()";
- break;
- case LDR_INVALID:
- msg = "invalid module";
- break;
- case LDR_BADOS:
- msg = "module doesn't support this OS";
- break;
- case LDR_MODSPECIFIC:
- msg = "module-specific error";
- break;
- default:
- msg = "unknown error";
- }
- if (name)
- xf86Msg(type, "%s: Failed to load module \"%s\" (%s, %d)\n",
- name, modname, msg, errmin);
- else
- xf86Msg(type, "Failed to load module \"%s\" (%s, %d)\n",
- modname, msg, errmin);
-}
-
-/* Given a module path or file name, return the module's canonical name */
-static char *
-LoaderGetCanonicalName(const char *modname, PatternPtr patterns)
-{
- char *str;
- const char *s;
- int len;
- PatternPtr p;
- regmatch_t match[2];
-
- /* Strip off any leading path */
- s = strrchr(modname, '/');
- if (s == NULL)
- s = modname;
- else
- s++;
-
- /* Find the first regex that is matched */
- for (p = patterns; p->pattern; p++)
- if (regexec(&p->rex, s, 2, match, 0) == 0 && match[1].rm_so != -1) {
- len = match[1].rm_eo - match[1].rm_so;
- str = malloc(len + 1);
- if (!str)
- return NULL;
- strncpy(str, s + match[1].rm_so, len);
- str[len] = '\0';
- return str;
- }
-
- /* If there is no match, return the whole name minus the leading path */
- return strdup(s);
-}
-
-/*
- * Return the module version information.
- */
-unsigned long
-LoaderGetModuleVersion(ModuleDescPtr mod)
-{
- if (!mod || mod == (ModuleDescPtr) 1 || !mod->VersionInfo)
- return 0;
-
- return MODULE_VERSION_NUMERIC(mod->VersionInfo->majorversion,
- mod->VersionInfo->minorversion,
- mod->VersionInfo->patchlevel);
-}
+/*
+ * Copyright 1995-1998 by Metro Link, 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 name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. 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) 1997-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).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "os.h"
+/* For stat() and related stuff */
+#define NO_OSLIB_PROTOTYPES
+#include "xf86_OSlib.h"
+#define LOADERDECLARATIONS
+#include "loaderProcs.h"
+#include "misc.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Xinput.h"
+#include "loader.h"
+#include "xf86Optrec.h"
+
+#include <sys/types.h>
+#include <regex.h>
+#include <dirent.h>
+#include <limits.h>
+
+typedef struct _pattern {
+ const char *pattern;
+ regex_t rex;
+} PatternRec, *PatternPtr;
+
+/* Prototypes for static functions */
+static char *FindModule(const char *, const char *, const char **,
+ PatternPtr);
+static Bool CheckVersion(const char *, XF86ModuleVersionInfo *,
+ const XF86ModReqInfo *);
+static void UnloadModuleOrDriver(ModuleDescPtr mod);
+static char *LoaderGetCanonicalName(const char *, PatternPtr);
+static void RemoveChild(ModuleDescPtr);
+static ModuleDescPtr doLoadModule(const char *, const char *, const char **,
+ const char **, pointer,
+ const XF86ModReqInfo *, int *, int *);
+
+const ModuleVersions LoaderVersionInfo = {
+ XORG_VERSION_CURRENT,
+ ABI_ANSIC_VERSION,
+ ABI_VIDEODRV_VERSION,
+ ABI_XINPUT_VERSION,
+ ABI_EXTENSION_VERSION,
+ ABI_FONT_VERSION
+};
+
+static void
+FreeStringList(char **paths)
+{
+ char **p;
+
+ if (!paths)
+ return;
+
+ for (p = paths; *p; p++)
+ free(*p);
+
+ free(paths);
+}
+
+static char **defaultPathList = NULL;
+
+static Bool
+PathIsAbsolute(const char *path)
+{
+ return *path == '/';
+}
+
+/*
+ * Convert a comma-separated path into a NULL-terminated array of path
+ * elements, rejecting any that are not full absolute paths, and appending
+ * a '/' when it isn't already present.
+ */
+static char **
+InitPathList(const char *path)
+{
+ char *fullpath = NULL;
+ char *elem = NULL;
+ char **list = NULL, **save = NULL;
+ int len;
+ int addslash;
+ int n = 0;
+
+ if (!path)
+ return defaultPathList;
+
+ fullpath = strdup(path);
+ if (!fullpath)
+ return NULL;
+ elem = strtok(fullpath, ",");
+ while (elem) {
+ if (PathIsAbsolute(elem))
+ {
+ len = strlen(elem);
+ addslash = (elem[len - 1] != '/');
+ if (addslash)
+ len++;
+ save = list;
+ list = realloc(list, (n + 2) * sizeof(char *));
+ if (!list) {
+ if (save) {
+ save[n] = NULL;
+ FreeStringList(save);
+ }
+ free(fullpath);
+ return NULL;
+ }
+ list[n] = malloc(len + 1);
+ if (!list[n]) {
+ FreeStringList(list);
+ free(fullpath);
+ return NULL;
+ }
+ strcpy(list[n], elem);
+ if (addslash) {
+ list[n][len - 1] = '/';
+ list[n][len] = '\0';
+ }
+ n++;
+ }
+ elem = strtok(NULL, ",");
+ }
+ if (list)
+ list[n] = NULL;
+ free(fullpath);
+ return list;
+}
+
+static void
+FreePathList(char **pathlist)
+{
+ if (pathlist && pathlist != defaultPathList)
+ FreeStringList(pathlist);
+}
+
+void
+LoaderSetPath(const char *path)
+{
+ if (!path)
+ return;
+
+ defaultPathList = InitPathList(path);
+}
+
+/* Standard set of module subdirectories to search, in order of preference */
+static const char *stdSubdirs[] = {
+ "",
+ "input/",
+ "drivers/",
+ "multimedia/",
+ "extensions/",
+ "internal/",
+ NULL
+};
+
+/*
+ * Standard set of module name patterns to check, in order of preference
+ * These are regular expressions (suitable for use with POSIX regex(3)).
+ *
+ * This list assumes that you're an ELFish platform and therefore your
+ * shared libraries are named something.so. If we're ever nuts enough
+ * to port this DDX to, say, Darwin, we'll need to fix this.
+ */
+static PatternRec stdPatterns[] = {
+ {"^lib(.*)\\.so$",},
+ {"(.*)_drv\\.so$",},
+ {"(.*)\\.so$",},
+ {NULL,}
+};
+
+static PatternPtr
+InitPatterns(const char **patternlist)
+{
+ char errmsg[80];
+ int i, e;
+ PatternPtr patterns = NULL;
+ PatternPtr p = NULL;
+ static int firstTime = 1;
+ const char **s;
+
+ if (firstTime) {
+ /* precompile stdPatterns */
+ firstTime = 0;
+ for (p = stdPatterns; p->pattern; p++)
+ if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) {
+ regerror(e, &p->rex, errmsg, sizeof(errmsg));
+ FatalError("InitPatterns: regcomp error for `%s': %s\n",
+ p->pattern, errmsg);
+ }
+ }
+
+ if (patternlist) {
+ for (i = 0, s = patternlist; *s; i++, s++)
+ if (*s == DEFAULT_LIST)
+ i += sizeof(stdPatterns) / sizeof(stdPatterns[0]) - 1 - 1;
+ patterns = malloc((i + 1) * sizeof(PatternRec));
+ if (!patterns) {
+ return NULL;
+ }
+ for (i = 0, s = patternlist; *s; i++, s++)
+ if (*s != DEFAULT_LIST) {
+ p = patterns + i;
+ p->pattern = *s;
+ if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) {
+ regerror(e, &p->rex, errmsg, sizeof(errmsg));
+ ErrorF("InitPatterns: regcomp error for `%s': %s\n",
+ p->pattern, errmsg);
+ i--;
+ }
+ } else {
+ for (p = stdPatterns; p->pattern; p++, i++)
+ patterns[i] = *p;
+ if (p != stdPatterns)
+ i--;
+ }
+ patterns[i].pattern = NULL;
+ } else
+ patterns = stdPatterns;
+ return patterns;
+}
+
+static void
+FreePatterns(PatternPtr patterns)
+{
+ if (patterns && patterns != stdPatterns)
+ free(patterns);
+}
+
+static const char **
+InitSubdirs(const char **subdirlist)
+{
+ int i;
+ const char **tmp_subdirlist = NULL;
+ char **subdirs = NULL;
+ const char **s, **stmp = NULL;
+ const char *osname;
+ const char *slash;
+ int oslen = 0, len;
+ Bool indefault;
+
+ if (subdirlist == NULL) {
+ subdirlist = tmp_subdirlist = malloc(2 * sizeof(char *));
+ if (subdirlist == NULL)
+ return NULL;
+ subdirlist[0] = DEFAULT_LIST;
+ subdirlist[1] = NULL;
+ }
+
+ LoaderGetOS(&osname, NULL, NULL, NULL);
+ oslen = strlen(osname);
+
+ {
+ /* Count number of entries and check for invalid paths */
+ for (i = 0, s = subdirlist; *s; i++, s++) {
+ if (*s == DEFAULT_LIST) {
+ i += sizeof(stdSubdirs) / sizeof(stdSubdirs[0]) - 1 - 1;
+ } else {
+ /*
+ * Path validity check. Don't allow absolute paths, or
+ * paths containing "..". To catch absolute paths on
+ * platforms that use driver letters, don't allow the ':'
+ * character to appear at all.
+ */
+ if (**s == '/' || **s == '\\' || strchr(*s, ':') ||
+ strstr(*s, "..")) {
+ xf86Msg(X_ERROR, "InitSubdirs: Bad subdir: \"%s\"\n", *s);
+ free(tmp_subdirlist);
+ return NULL;
+ }
+ }
+ }
+ subdirs = malloc((i * 2 + 1) * sizeof(char *));
+ if (!subdirs) {
+ free(tmp_subdirlist);
+ return NULL;
+ }
+ i = 0;
+ s = subdirlist;
+ indefault = FALSE;
+ while (*s) {
+ if (*s == DEFAULT_LIST) {
+ /* Divert to the default list */
+ indefault = TRUE;
+ stmp = ++s;
+ s = stdSubdirs;
+ }
+ len = strlen(*s);
+ if (**s && (*s)[len - 1] != '/') {
+ slash = "/";
+ len++;
+ } else
+ slash = "";
+ len += oslen + 2;
+ if (!(subdirs[i] = malloc(len))) {
+ while (--i >= 0)
+ free(subdirs[i]);
+ free(subdirs);
+ free(tmp_subdirlist);
+ return NULL;
+ }
+ /* tack on the OS name */
+ sprintf(subdirs[i], "%s%s%s/", *s, slash, osname);
+ i++;
+ /* path as given */
+ subdirs[i] = strdup(*s);
+ i++;
+ s++;
+ if (indefault && !s) {
+ /* revert back to the main list */
+ indefault = FALSE;
+ s = stmp;
+ }
+ }
+ subdirs[i] = NULL;
+ }
+ free(tmp_subdirlist);
+ return (const char **)subdirs;
+}
+
+static void
+FreeSubdirs(const char **subdirs)
+{
+ const char **s;
+
+ if (subdirs) {
+ for (s = subdirs; *s; s++)
+ free((char *)*s);
+ free(subdirs);
+ }
+}
+
+static char *
+FindModuleInSubdir(const char *dirpath, const char *module)
+{
+ struct dirent *direntry = NULL;
+ DIR *dir = NULL;
+ char *ret = NULL, tmpBuf[PATH_MAX];
+ struct stat stat_buf;
+
+ dir = opendir(dirpath);
+ if (!dir)
+ return NULL;
+
+ while ((direntry = readdir(dir))) {
+ if (direntry->d_name[0] == '.')
+ continue;
+ snprintf(tmpBuf, PATH_MAX, "%s%s/", dirpath, direntry->d_name);
+ /* the stat with the appended / fails for normal files,
+ and works for sub dirs fine, looks a bit strange in strace
+ but does seem to work */
+ if ((stat(tmpBuf, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)) {
+ if ((ret = FindModuleInSubdir(tmpBuf, module)))
+ break;
+ continue;
+ }
+
+ snprintf(tmpBuf, PATH_MAX, "lib%s.so", module);
+ if (strcmp(direntry->d_name, tmpBuf) == 0) {
+ if (asprintf(&ret, "%s%s", dirpath, tmpBuf) == -1)
+ ret = NULL;
+ break;
+ }
+
+ snprintf(tmpBuf, PATH_MAX, "%s_drv.so", module);
+ if (strcmp(direntry->d_name, tmpBuf) == 0) {
+ if (asprintf(&ret, "%s%s", dirpath, tmpBuf) == -1)
+ ret = NULL;
+ break;
+ }
+
+ snprintf(tmpBuf, PATH_MAX, "%s.so", module);
+ if (strcmp(direntry->d_name, tmpBuf) == 0) {
+ if (asprintf(&ret, "%s%s", dirpath, tmpBuf) == -1)
+ ret = NULL;
+ break;
+ }
+ }
+
+ closedir(dir);
+ return ret;
+}
+
+static char *
+FindModule(const char *module, const char *dirname, const char **subdirlist,
+ PatternPtr patterns)
+{
+ char buf[PATH_MAX + 1];
+ char *dirpath = NULL;
+ char *name = NULL;
+ int dirlen;
+ const char **subdirs = NULL;
+ const char **s;
+
+ dirpath = (char *)dirname;
+ if (strlen(dirpath) > PATH_MAX)
+ return NULL;
+
+ subdirs = InitSubdirs(subdirlist);
+ if (!subdirs)
+ return NULL;
+
+ for (s = subdirs; *s; s++) {
+ if ((dirlen = strlen(dirpath) + strlen(*s)) > PATH_MAX)
+ continue;
+ strcpy(buf, dirpath);
+ strcat(buf, *s);
+ if ((name = FindModuleInSubdir(buf, module)))
+ break;
+ }
+
+ FreeSubdirs(subdirs);
+ if (dirpath != dirname)
+ free(dirpath);
+
+ return name;
+}
+
+char **
+LoaderListDirs(const char **subdirlist, const char **patternlist)
+{
+ char buf[PATH_MAX + 1];
+ char **pathlist;
+ char **elem;
+ const char **subdirs;
+ const char **s;
+ PatternPtr patterns;
+ PatternPtr p;
+ DIR *d;
+ struct dirent *dp;
+ regmatch_t match[2];
+ struct stat stat_buf;
+ int len, dirlen;
+ char *fp;
+ char **listing = NULL;
+ char **save;
+ char **ret = NULL;
+ int n = 0;
+
+ if (!(pathlist = InitPathList(NULL)))
+ return NULL;
+ if (!(subdirs = InitSubdirs(subdirlist)))
+ goto bail;
+ if (!(patterns = InitPatterns(patternlist)))
+ goto bail;
+
+ for (elem = pathlist; *elem; elem++) {
+ for (s = subdirs; *s; s++) {
+ if ((dirlen = strlen(*elem) + strlen(*s)) > PATH_MAX)
+ continue;
+ strcpy(buf, *elem);
+ strcat(buf, *s);
+ fp = buf + dirlen;
+ if (stat(buf, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode) &&
+ (d = opendir(buf))) {
+ if (buf[dirlen - 1] != '/') {
+ buf[dirlen++] = '/';
+ fp++;
+ }
+ while ((dp = readdir(d))) {
+ if (dirlen + strlen(dp->d_name) > PATH_MAX)
+ continue;
+ strcpy(fp, dp->d_name);
+ if (!(stat(buf, &stat_buf) == 0 &&
+ S_ISREG(stat_buf.st_mode)))
+ continue;
+ for (p = patterns; p->pattern; p++) {
+ if (regexec(&p->rex, dp->d_name, 2, match, 0) == 0 &&
+ match[1].rm_so != -1) {
+ len = match[1].rm_eo - match[1].rm_so;
+ save = listing;
+ listing = realloc(listing,
+ (n + 2) * sizeof(char *));
+ if (!listing) {
+ if (save) {
+ save[n] = NULL;
+ FreeStringList(save);
+ }
+ closedir(d);
+ goto bail;
+ }
+ listing[n] = malloc(len + 1);
+ if (!listing[n]) {
+ FreeStringList(listing);
+ closedir(d);
+ goto bail;
+ }
+ strncpy(listing[n], dp->d_name + match[1].rm_so,
+ len);
+ listing[n][len] = '\0';
+ n++;
+ break;
+ }
+ }
+ }
+ closedir(d);
+ }
+ }
+ }
+ if (listing)
+ listing[n] = NULL;
+ ret = listing;
+
+bail:
+ FreePatterns(patterns);
+ FreeSubdirs(subdirs);
+ FreePathList(pathlist);
+ return ret;
+}
+
+void
+LoaderFreeDirList(char **list)
+{
+ FreeStringList(list);
+}
+
+static Bool
+CheckVersion(const char *module, XF86ModuleVersionInfo * data,
+ const XF86ModReqInfo * req)
+{
+ int vercode[4];
+ char verstr[4];
+ long ver = data->xf86version;
+ MessageType errtype;
+
+ xf86Msg(X_INFO, "Module %s: vendor=\"%s\"\n",
+ data->modname ? data->modname : "UNKNOWN!",
+ data->vendor ? data->vendor : "UNKNOWN!");
+
+ /* Check for the different scheme used in XFree86 4.0.x releases:
+ * ((((((((major << 7) | minor) << 7) | subminor) << 5) | beta) << 5) | alpha)
+ * Since it wasn't used in 4.1.0 or later, limit to versions in the 4.0.x
+ * range, which limits the overlap with the new version scheme to conflicts
+ * with 6.71.8.764 through 6.72.39.934.
+ */
+ if ((ver > (4 << 24)) && (ver < ( (4 << 24) + (1 << 17)))) {
+ /* 4.0.x and earlier */
+ verstr[1] = verstr[3] = 0;
+ verstr[2] = (ver & 0x1f) ? (ver & 0x1f) + 'a' - 1 : 0;
+ ver >>= 5;
+ verstr[0] = (ver & 0x1f) ? (ver & 0x1f) + 'A' - 1 : 0;
+ ver >>= 5;
+ vercode[2] = ver & 0x7f;
+ ver >>= 7;
+ vercode[1] = ver & 0x7f;
+ ver >>= 7;
+ vercode[0] = ver;
+ xf86ErrorF("\tcompiled for %d.%d", vercode[0], vercode[1]);
+ if (vercode[2] != 0)
+ xf86ErrorF(".%d", vercode[2]);
+ xf86ErrorF("%s%s, module version = %d.%d.%d\n", verstr, verstr + 2,
+ data->majorversion, data->minorversion, data->patchlevel);
+ } else {
+ vercode[0] = ver / 10000000;
+ vercode[1] = (ver / 100000) % 100;
+ vercode[2] = (ver / 1000) % 100;
+ vercode[3] = ver % 1000;
+ xf86ErrorF("\tcompiled for %d.%d.%d", vercode[0], vercode[1],
+ vercode[2]);
+ if (vercode[3] != 0)
+ xf86ErrorF(".%d", vercode[3]);
+ xf86ErrorF(", module version = %d.%d.%d\n", data->majorversion,
+ data->minorversion, data->patchlevel);
+ }
+
+ if (data->moduleclass)
+ xf86ErrorFVerb(2, "\tModule class: %s\n", data->moduleclass);
+
+ ver = -1;
+ if (data->abiclass) {
+ int abimaj, abimin;
+ int vermaj, vermin;
+
+ if (!strcmp(data->abiclass, ABI_CLASS_ANSIC))
+ ver = LoaderVersionInfo.ansicVersion;
+ else if (!strcmp(data->abiclass, ABI_CLASS_VIDEODRV))
+ ver = LoaderVersionInfo.videodrvVersion;
+ else if (!strcmp(data->abiclass, ABI_CLASS_XINPUT))
+ ver = LoaderVersionInfo.xinputVersion;
+ else if (!strcmp(data->abiclass, ABI_CLASS_EXTENSION))
+ ver = LoaderVersionInfo.extensionVersion;
+ else if (!strcmp(data->abiclass, ABI_CLASS_FONT))
+ ver = LoaderVersionInfo.fontVersion;
+
+ abimaj = GET_ABI_MAJOR(data->abiversion);
+ abimin = GET_ABI_MINOR(data->abiversion);
+ xf86ErrorFVerb(2, "\tABI class: %s, version %d.%d\n",
+ data->abiclass, abimaj, abimin);
+ if (ver != -1) {
+ vermaj = GET_ABI_MAJOR(ver);
+ vermin = GET_ABI_MINOR(ver);
+ if (abimaj != vermaj) {
+ if (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL)
+ errtype = X_WARNING;
+ else
+ errtype = X_ERROR;
+ xf86MsgVerb(errtype, 0,
+ "module ABI major version (%d) doesn't"
+ " match the server's version (%d)\n",
+ abimaj, vermaj);
+ if (!(LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL))
+ return FALSE;
+ } else if (abimin > vermin) {
+ if (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL)
+ errtype = X_WARNING;
+ else
+ errtype = X_ERROR;
+ xf86MsgVerb(errtype, 0,
+ "module ABI minor version (%d) is "
+ "newer than the server's version "
+ "(%d)\n", abimin, vermin);
+ if (!(LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL))
+ return FALSE;
+ }
+ }
+ }
+
+ /* Check against requirements that the caller has specified */
+ if (req) {
+ if (req->majorversion != MAJOR_UNSPEC) {
+ if (data->majorversion != req->majorversion) {
+ xf86MsgVerb(X_WARNING, 2, "module major version (%d) "
+ "doesn't match required major version (%d)\n",
+ data->majorversion, req->majorversion);
+ return FALSE;
+ } else if (req->minorversion != MINOR_UNSPEC) {
+ if (data->minorversion < req->minorversion) {
+ xf86MsgVerb(X_WARNING, 2, "module minor version (%d) "
+ "is less than the required minor version (%d)\n",
+ data->minorversion, req->minorversion);
+ return FALSE;
+ } else if (data->minorversion == req->minorversion &&
+ req->patchlevel != PATCH_UNSPEC) {
+ if (data->patchlevel < req->patchlevel) {
+ xf86MsgVerb(X_WARNING, 2, "module patch level (%d) "
+ "is less than the required patch level (%d)\n",
+ data->patchlevel, req->patchlevel);
+ return FALSE;
+ }
+ }
+ }
+ }
+ if (req->moduleclass) {
+ if (!data->moduleclass ||
+ strcmp(req->moduleclass, data->moduleclass)) {
+ xf86MsgVerb(X_WARNING, 2, "Module class (%s) doesn't match "
+ "the required class (%s)\n",
+ data->moduleclass ? data->moduleclass : "<NONE>",
+ req->moduleclass);
+ return FALSE;
+ }
+ } else if (req->abiclass != ABI_CLASS_NONE) {
+ if (!data->abiclass || strcmp(req->abiclass, data->abiclass)) {
+ xf86MsgVerb(X_WARNING, 2, "ABI class (%s) doesn't match the "
+ "required ABI class (%s)\n",
+ data->abiclass ? data->abiclass : "<NONE>",
+ req->abiclass);
+ return FALSE;
+ }
+ }
+ if ((req->abiclass != ABI_CLASS_NONE) &&
+ req->abiversion != ABI_VERS_UNSPEC) {
+ int reqmaj, reqmin, maj, min;
+
+ reqmaj = GET_ABI_MAJOR(req->abiversion);
+ reqmin = GET_ABI_MINOR(req->abiversion);
+ maj = GET_ABI_MAJOR(data->abiversion);
+ min = GET_ABI_MINOR(data->abiversion);
+ if (maj != reqmaj) {
+ xf86MsgVerb(X_WARNING, 2, "ABI major version (%d) doesn't "
+ "match the required ABI major version (%d)\n",
+ maj, reqmaj);
+ return FALSE;
+ }
+ /* XXX Maybe this should be the other way around? */
+ if (min > reqmin) {
+ xf86MsgVerb(X_WARNING, 2, "module ABI minor version (%d) "
+ "is newer than that available (%d)\n", min, reqmin);
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+static ModuleDescPtr
+AddSibling(ModuleDescPtr head, ModuleDescPtr new)
+{
+ new->sib = head;
+ return new;
+}
+
+pointer
+LoadSubModule(pointer _parent, const char *module,
+ const char **subdirlist, const char **patternlist,
+ pointer options, const XF86ModReqInfo * modreq,
+ int *errmaj, int *errmin)
+{
+ ModuleDescPtr submod;
+ ModuleDescPtr parent = (ModuleDescPtr)_parent;
+
+ xf86MsgVerb(X_INFO, 3, "Loading sub module \"%s\"\n", module);
+
+ if (PathIsAbsolute(module)) {
+ xf86Msg(X_ERROR,
+ "LoadSubModule: Absolute module path not permitted: \"%s\"\n",
+ module);
+ if (errmaj)
+ *errmaj = LDR_BADUSAGE;
+ if (errmin)
+ *errmin = 0;
+ return NULL;
+ }
+
+ submod = doLoadModule(module, NULL, subdirlist, patternlist, options,
+ modreq, errmaj, errmin);
+ if (submod && submod != (ModuleDescPtr) 1) {
+ parent->child = AddSibling(parent->child, submod);
+ submod->parent = parent;
+ }
+ return submod;
+}
+
+static ModuleDescPtr
+NewModuleDesc(const char *name)
+{
+ ModuleDescPtr mdp = calloc(1, sizeof(ModuleDesc));
+
+ if (mdp)
+ mdp->name = xstrdup(name);
+
+ return mdp;
+}
+
+ModuleDescPtr
+DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent)
+{
+ ModuleDescPtr ret;
+ int errmaj, errmin;
+
+ if (!mod)
+ return NULL;
+
+ ret = NewModuleDesc(mod->name);
+ if (ret == NULL)
+ return NULL;
+
+ if (!(ret->handle = LoaderOpen(mod->path, &errmaj, &errmin))) {
+ free(ret);
+ return NULL;
+ }
+
+ ret->SetupProc = mod->SetupProc;
+ ret->TearDownProc = mod->TearDownProc;
+ ret->TearDownData = NULL;
+ ret->child = DuplicateModule(mod->child, ret);
+ ret->sib = DuplicateModule(mod->sib, parent);
+ ret->parent = parent;
+ ret->VersionInfo = mod->VersionInfo;
+ ret->path = strdup(mod->path);
+
+ return ret;
+}
+
+static const char *compiled_in_modules[] = {
+ "ddc",
+ "i2c",
+ "ramdac",
+ NULL
+};
+
+static ModuleDescPtr
+doLoadModule(const char *module, const char *path, const char **subdirlist,
+ const char **patternlist, pointer options,
+ const XF86ModReqInfo * modreq,
+ int *errmaj, int *errmin)
+{
+ XF86ModuleData *initdata = NULL;
+ char **pathlist = NULL;
+ char *found = NULL;
+ char *name = NULL;
+ char **path_elem = NULL;
+ char *p = NULL;
+ ModuleDescPtr ret = NULL;
+ PatternPtr patterns = NULL;
+ int noncanonical = 0;
+ char *m = NULL;
+ const char **cim;
+
+ xf86MsgVerb(X_INFO, 3, "LoadModule: \"%s\"", module);
+
+ patterns = InitPatterns(patternlist);
+ name = LoaderGetCanonicalName(module, patterns);
+ noncanonical = (name && strcmp(module, name) != 0);
+ if (noncanonical) {
+ xf86ErrorFVerb(3, " (%s)\n", name);
+ xf86MsgVerb(X_WARNING, 1,
+ "LoadModule: given non-canonical module name \"%s\"\n",
+ module);
+ m = name;
+ } else {
+ xf86ErrorFVerb(3, "\n");
+ m = (char *)module;
+ }
+
+ for (cim = compiled_in_modules; *cim; cim++)
+ if (!strcmp (m, *cim))
+ {
+ xf86MsgVerb(X_INFO, 3, "Module \"%s\" already built-in\n", m);
+ ret = (ModuleDescPtr) 1;
+ goto LoadModule_exit;
+ }
+
+ if (!name) {
+ if (errmaj)
+ *errmaj = LDR_BADUSAGE;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ ret = NewModuleDesc(name);
+ if (!ret) {
+ if (errmaj)
+ *errmaj = LDR_NOMEM;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+
+ pathlist = InitPathList(path);
+ if (!pathlist) {
+ /* This could be a malloc failure too */
+ if (errmaj)
+ *errmaj = LDR_BADUSAGE;
+ if (errmin)
+ *errmin = 1;
+ goto LoadModule_fail;
+ }
+
+ /*
+ * if the module name is not a full pathname, we need to
+ * check the elements in the path
+ */
+ if (PathIsAbsolute(module))
+ found = xstrdup(module);
+ path_elem = pathlist;
+ while (!found && *path_elem != NULL) {
+ found = FindModule(m, *path_elem, subdirlist, patterns);
+ path_elem++;
+ /*
+ * When the module name isn't the canonical name, search for the
+ * former if no match was found for the latter.
+ */
+ if (!*path_elem && m == name) {
+ path_elem = pathlist;
+ m = (char *)module;
+ }
+ }
+
+ /*
+ * did we find the module?
+ */
+ if (!found) {
+ xf86Msg(X_WARNING, "Warning, couldn't open module %s\n", module);
+ if (errmaj)
+ *errmaj = LDR_NOENT;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ ret->handle = LoaderOpen(found, errmaj, errmin);
+ if (ret->handle < 0)
+ goto LoadModule_fail;
+ ret->path = strdup(found);
+
+ /* drop any explicit suffix from the module name */
+ p = strchr(name, '.');
+ if (p)
+ *p = '\0';
+
+ /*
+ * now check if the special data object <modulename>ModuleData is
+ * present.
+ */
+ if (asprintf(&p, "%sModuleData", name) == -1) {
+ p = NULL;
+ if (errmaj)
+ *errmaj = LDR_NOMEM;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ initdata = LoaderSymbol(p);
+ if (initdata) {
+ ModuleSetupProc setup;
+ ModuleTearDownProc teardown;
+ XF86ModuleVersionInfo *vers;
+
+ vers = initdata->vers;
+ setup = initdata->setup;
+ teardown = initdata->teardown;
+
+ if (vers) {
+ if (!CheckVersion(module, vers, modreq)) {
+ if (errmaj)
+ *errmaj = LDR_MISMATCH;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ } else {
+ xf86Msg(X_ERROR,
+ "LoadModule: Module %s does not supply"
+ " version information\n", module);
+ if (errmaj)
+ *errmaj = LDR_INVALID;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ if (setup)
+ ret->SetupProc = setup;
+ if (teardown)
+ ret->TearDownProc = teardown;
+ ret->VersionInfo = vers;
+ } else {
+ /* No initdata is OK for external modules */
+ if (options == EXTERN_MODULE)
+ goto LoadModule_exit;
+
+ /* no initdata, fail the load */
+ xf86Msg(X_ERROR, "LoadModule: Module %s does not have a %s "
+ "data object.\n", module, p);
+ if (errmaj)
+ *errmaj = LDR_INVALID;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ if (ret->SetupProc) {
+ ret->TearDownData = ret->SetupProc(ret, options, errmaj, errmin);
+ if (!ret->TearDownData) {
+ goto LoadModule_fail;
+ }
+ } else if (options) {
+ xf86Msg(X_WARNING, "Module Options present, but no SetupProc "
+ "available for %s\n", module);
+ }
+ goto LoadModule_exit;
+
+ LoadModule_fail:
+ UnloadModule(ret);
+ ret = NULL;
+
+ LoadModule_exit:
+ FreePathList(pathlist);
+ FreePatterns(patterns);
+ free(found);
+ free(name);
+ free(p);
+
+ return ret;
+}
+
+/*
+ * LoadModule: load a module
+ *
+ * module The module name. Normally this is not a filename but the
+ * module's "canonical name. A full pathname is, however,
+ * also accepted.
+ * path A comma separated list of module directories.
+ * subdirlist A NULL terminated list of subdirectories to search. When
+ * NULL, the default "stdSubdirs" list is used. The default
+ * list is also substituted for entries with value DEFAULT_LIST.
+ * patternlist A NULL terminated list of regular expressions used to find
+ * module filenames. Each regex should contain exactly one
+ * subexpression that corresponds to the canonical module name.
+ * When NULL, the default "stdPatterns" list is used. The
+ * default list is also substituted for entries with value
+ * DEFAULT_LIST.
+ * options A NULL terminated list of Options that are passed to the
+ * module's SetupProc function.
+ * modreq An optional XF86ModReqInfo* containing
+ * version/ABI/vendor-ABI requirements to check for when
+ * loading the module. The following fields of the
+ * XF86ModReqInfo struct are checked:
+ * majorversion - must match the module's majorversion exactly
+ * minorversion - the module's minorversion must be >= this
+ * patchlevel - the module's minorversion.patchlevel must be
+ * >= this. Patchlevel is ignored when
+ * minorversion is not set.
+ * abiclass - (string) must match the module's abiclass
+ * abiversion - must be consistent with the module's
+ * abiversion (major equal, minor no older)
+ * moduleclass - string must match the module's moduleclass
+ * string
+ * "don't care" values are ~0 for numbers, and NULL for strings
+ * errmaj Major error return.
+ * errmin Minor error return.
+ *
+ */
+ModuleDescPtr
+LoadModule(const char *module, const char *path, const char **subdirlist,
+ const char **patternlist, pointer options,
+ const XF86ModReqInfo * modreq, int *errmaj, int *errmin)
+{
+ return doLoadModule(module, path, subdirlist, patternlist, options,
+ modreq, errmaj, errmin);
+}
+
+void
+UnloadModule(pointer mod)
+{
+ UnloadModuleOrDriver((ModuleDescPtr)mod);
+}
+
+static void
+UnloadModuleOrDriver(ModuleDescPtr mod)
+{
+ if (mod == (ModuleDescPtr) 1)
+ return;
+
+ if (mod == NULL || mod->name == NULL)
+ return;
+
+ xf86MsgVerb(X_INFO, 3, "UnloadModule: \"%s\"\n", mod->name);
+
+ if ((mod->TearDownProc) && (mod->TearDownData))
+ mod->TearDownProc(mod->TearDownData);
+ LoaderUnload(mod->name, mod->handle);
+
+ if (mod->child)
+ UnloadModuleOrDriver(mod->child);
+ if (mod->sib)
+ UnloadModuleOrDriver(mod->sib);
+ free(mod->path);
+ free(mod->name);
+ free(mod);
+}
+
+void
+UnloadSubModule(pointer _mod)
+{
+ ModuleDescPtr mod = (ModuleDescPtr)_mod;
+
+ if (mod == NULL || mod->name == NULL)
+ return;
+
+ xf86MsgVerb(X_INFO, 3, "UnloadSubModule: \"%s\"\n", mod->name);
+
+ if ((mod->TearDownProc) && (mod->TearDownData))
+ mod->TearDownProc(mod->TearDownData);
+ LoaderUnload(mod->name, mod->handle);
+
+ RemoveChild(mod);
+
+ if (mod->child)
+ UnloadModuleOrDriver(mod->child);
+
+ free(mod->path);
+ free(mod->name);
+ free(mod);
+}
+
+static void
+RemoveChild(ModuleDescPtr child)
+{
+ ModuleDescPtr mdp;
+ ModuleDescPtr prevsib;
+ ModuleDescPtr parent;
+
+ if (!child->parent)
+ return;
+
+ parent = child->parent;
+ if (parent->child == child) {
+ parent->child = child->sib;
+ return;
+ }
+
+ prevsib = parent->child;
+ mdp = prevsib->sib;
+ while (mdp && mdp != child) {
+ prevsib = mdp;
+ mdp = mdp->sib;
+ }
+ if (mdp == child)
+ prevsib->sib = child->sib;
+ return;
+}
+
+void
+LoaderErrorMsg(const char *name, const char *modname, int errmaj, int errmin)
+{
+ const char *msg;
+ MessageType type = X_ERROR;
+
+ switch (errmaj) {
+ case LDR_NOERROR:
+ msg = "no error";
+ break;
+ case LDR_NOMEM:
+ msg = "out of memory";
+ break;
+ case LDR_NOENT:
+ msg = "module does not exist";
+ break;
+ case LDR_NOSUBENT:
+ msg = "a required submodule could not be loaded";
+ break;
+ case LDR_NOSPACE:
+ msg = "too many modules";
+ break;
+ case LDR_NOMODOPEN:
+ msg = "open failed";
+ break;
+ case LDR_UNKTYPE:
+ msg = "unknown module type";
+ break;
+ case LDR_NOLOAD:
+ msg = "loader failed";
+ break;
+ case LDR_ONCEONLY:
+ msg = "already loaded";
+ type = X_INFO;
+ break;
+ case LDR_NOPORTOPEN:
+ msg = "port open failed";
+ break;
+ case LDR_NOHARDWARE:
+ msg = "no hardware found";
+ break;
+ case LDR_MISMATCH:
+ msg = "module requirement mismatch";
+ break;
+ case LDR_BADUSAGE:
+ msg = "invalid argument(s) to LoadModule()";
+ break;
+ case LDR_INVALID:
+ msg = "invalid module";
+ break;
+ case LDR_BADOS:
+ msg = "module doesn't support this OS";
+ break;
+ case LDR_MODSPECIFIC:
+ msg = "module-specific error";
+ break;
+ default:
+ msg = "unknown error";
+ }
+ if (name)
+ xf86Msg(type, "%s: Failed to load module \"%s\" (%s, %d)\n",
+ name, modname, msg, errmin);
+ else
+ xf86Msg(type, "Failed to load module \"%s\" (%s, %d)\n",
+ modname, msg, errmin);
+}
+
+/* Given a module path or file name, return the module's canonical name */
+static char *
+LoaderGetCanonicalName(const char *modname, PatternPtr patterns)
+{
+ char *str;
+ const char *s;
+ int len;
+ PatternPtr p;
+ regmatch_t match[2];
+
+ /* Strip off any leading path */
+ s = strrchr(modname, '/');
+ if (s == NULL)
+ s = modname;
+ else
+ s++;
+
+ /* Find the first regex that is matched */
+ for (p = patterns; p->pattern; p++)
+ if (regexec(&p->rex, s, 2, match, 0) == 0 && match[1].rm_so != -1) {
+ len = match[1].rm_eo - match[1].rm_so;
+ str = malloc(len + 1);
+ if (!str)
+ return NULL;
+ strncpy(str, s + match[1].rm_so, len);
+ str[len] = '\0';
+ return str;
+ }
+
+ /* If there is no match, return the whole name minus the leading path */
+ return strdup(s);
+}
+
+/*
+ * Return the module version information.
+ */
+unsigned long
+LoaderGetModuleVersion(ModuleDescPtr mod)
+{
+ if (!mod || mod == (ModuleDescPtr) 1 || !mod->VersionInfo)
+ return 0;
+
+ return MODULE_VERSION_NUMERIC(mod->VersionInfo->majorversion,
+ mod->VersionInfo->minorversion,
+ mod->VersionInfo->patchlevel);
+}
diff --git a/xorg-server/hw/xfree86/loader/sdksyms.sh b/xorg-server/hw/xfree86/loader/sdksyms.sh
index 18bb73523..6f5082ae5 100644
--- a/xorg-server/hw/xfree86/loader/sdksyms.sh
+++ b/xorg-server/hw/xfree86/loader/sdksyms.sh
@@ -1,425 +1,425 @@
-#!/bin/sh
-
-cat > sdksyms.c << EOF
-/* This file is automatically generated by sdksyms.sh. */
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-
-/* These must be included first */
-#include "misc.h"
-#include "miscstruct.h"
-
-
-/* render/Makefile.am */
-#include "picture.h"
-#include "mipict.h"
-#include "glyphstr.h"
-#include "picturestr.h"
-
-
-/* fb/Makefile.am -- module */
-/*
-#include "fb.h"
-#include "fbrop.h"
-#include "fboverlay.h"
-#include "wfbrename.h"
-#include "fbpict.h"
- */
-
-
-/* miext/shadow/Makefile.am -- module */
-/*
-#include "shadow.h"
- */
-
-
-/* miext/damage/Makefile.am */
-#include "damage.h"
-#include "damagestr.h"
-
-/* miext/sync/Makefile.am */
-#include "misync.h"
-#include "misyncstr.h"
-
-/* Xext/Makefile.am -- half is module, half is builtin */
-/*
-#include "xvdix.h"
-#include "xvmcext.h"
- */
-#include "geext.h"
-#include "geint.h"
-#include "shmint.h"
-#include "syncsdk.h"
-#if XINERAMA
-# include "panoramiXsrv.h"
-# include "panoramiX.h"
-#endif
-
-
-/* hw/xfree86/int10/Makefile.am -- module */
-/*
-#include "xf86int10.h"
- */
-
-
-/* hw/xfree86/i2c/Makefile.am -- "mostly" modules */
-#include "xf86i2c.h"
-/*
-#include "bt829.h"
-#include "fi1236.h"
-#include "msp3430.h"
-#include "tda8425.h"
-#include "tda9850.h"
-#include "tda9885.h"
-#include "uda1380.h"
-#include "i2c_def.h"
- */
-
-
-/* hw/xfree86/modes/Makefile.am */
-#include "xf86Crtc.h"
-#include "xf86Modes.h"
-#include "xf86RandR12.h"
-/* #include "xf86Rename.h" */
-
-
-/* hw/xfree86/ddc/Makefile.am */
-#include "edid.h"
-#include "xf86DDC.h"
-
-
-/* hw/xfree86/dri2/Makefile.am -- module */
-/*
-#if DRI2
-# include "dri2.h"
-#endif
- */
-
-
-/* hw/xfree86/vgahw/Makefile.am -- module */
-/*
-#include "vgaHW.h"
- */
-
-
-/* hw/xfree86/fbdevhw/Makefile.am -- module */
-/*
-#include "fbdevhw.h"
- */
-
-
-/* hw/xfree86/common/Makefile.am */
-#include "compiler.h"
-#include "fourcc.h"
-#include "xf86.h"
-#include "xf86Module.h"
-#include "xf86Opt.h"
-#include "xf86PciInfo.h"
-#include "xf86Priv.h"
-#include "xf86Privstr.h"
-#include "xf86cmap.h"
-#include "xf86fbman.h"
-#include "xf86str.h"
-#include "xf86Xinput.h"
-#include "xf86VGAarbiter.h"
-#include "xisb.h"
-#if XV
-# include "xf86xv.h"
-# include "xf86xvmc.h"
-# include "xf86xvpriv.h"
-#endif
-/* XF86VidMode code is in libextmod module */
-/*
-#if XF86VIDMODE
-# include "vidmodeproc.h"
-#endif
- */
-#include "xorgVersion.h"
-#if defined(__sparc__) || defined(__sparc)
-# include "xf86sbusBus.h"
-#endif
-
-
-/* hw/xfree86/ramdac/Makefile.am */
-#include "BT.h"
-#include "IBM.h"
-#include "TI.h"
-#include "xf86Cursor.h"
-#include "xf86RamDac.h"
-
-
-/* hw/xfree86/shadowfb/Makefile.am -- module */
-/*
-#include "shadowfb.h"
- */
-
-
-/* hw/xfree86/os-support/solaris/Makefile.am */
-#if defined(sun386)
-# include "agpgart.h"
-#endif
-
-
-/* hw/xfree86/os-support/Makefile.am */
-#include "xf86_OSproc.h"
-#include "xf86_OSlib.h"
-
-
-/* hw/xfree86/os-support/bus/Makefile.am */
-#include "xf86Pci.h"
-#if defined(__sparc__) || defined(__sparc)
-# include "xf86Sbus.h"
-#endif
-
-
-/* hw/xfree86/xaa/Makefile.am -- module */
-/*
-#include "xaa.h"
-#include "xaalocal.h"
-#include "xaarop.h"
- */
-
-
-/* hw/xfree86/dixmods/extmod/Makefile.am -- module */
-/*
-#include "dgaproc.h"
- */
-
-
-/* hw/xfree86/parser/Makefile.am */
-#include "xf86Parser.h"
-#include "xf86Optrec.h"
-
-
-/* hw/xfree86/vbe/Makefile.am -- module */
-/*
-#include "vbe.h"
-#include "vbeModes.h"
- */
-
-
-/* hw/xfree86/dri/Makefile.am -- module */
-/*
-#if XF86DRI
-# include "dri.h"
-# include "sarea.h"
-# include "dristruct.h"
-#endif
- */
-
-
-/* mi/Makefile.am */
-#include "micmap.h"
-#include "miline.h"
-#include "mipointer.h"
-#include "mi.h"
-#include "mibstore.h"
-#include "migc.h"
-#include "mipointrst.h"
-#include "mizerarc.h"
-#include "micoord.h"
-#include "mifillarc.h"
-#include "mispans.h"
-#include "miwideline.h"
-#include "mistruct.h"
-#include "mifpoly.h"
-#include "mioverlay.h"
-
-
-/* randr/Makefile.am */
-#include "randrstr.h"
-#include "rrtransform.h"
-
-
-/* dbe/Makefile.am -- module */
-/*
-#include "dbestruct.h"
- */
-
-
-/* exa/Makefile.am -- module */
-/*
-#include "exa.h"
- */
-
-
-/* xfixes/Makefile.am */
-#include "xfixes.h"
-
-
-/* include/Makefile.am */
-#include "XIstubs.h"
-#include "Xprintf.h"
-#include "closestr.h"
-#include "closure.h"
-#include "colormap.h"
-#include "colormapst.h"
-#include "hotplug.h"
-#include "client.h"
-#include "cursor.h"
-#include "cursorstr.h"
-#include "dix.h"
-#include "dixaccess.h"
-#include "dixevents.h"
-#include "dixfont.h"
-#include "dixfontstr.h"
-#include "dixgrabs.h"
-#include "dixstruct.h"
-#include "exevents.h"
-#include "extension.h"
-#include "extinit.h"
-#include "extnsionst.h"
-#include "gc.h"
-#include "gcstruct.h"
-#include "globals.h"
-#include "input.h"
-#include "inputstr.h"
-/* already included */
-/*
-#include "misc.h"
-#include "miscstruct.h"
- */
-#include "opaque.h"
-#include "os.h"
-#include "pixmap.h"
-#include "pixmapstr.h"
-#include "privates.h"
-#include "property.h"
-#include "propertyst.h"
-#include "ptrveloc.h"
-#include "region.h"
-#include "regionstr.h"
-#include "registry.h"
-#include "resource.h"
-#include "rgb.h"
-#include "screenint.h"
-#include "scrnintstr.h"
-#include "selection.h"
-#include "servermd.h"
-#include "site.h"
-#include "swaprep.h"
-#include "swapreq.h"
-#include "validate.h"
-#include "window.h"
-#include "windowstr.h"
-#include "xace.h"
-#include "xkbfile.h"
-#include "xkbsrv.h"
-#include "xkbstr.h"
-#include "xkbrules.h"
-#include "xserver-properties.h"
-
-EOF
-
-topdir=$1
-shift
-LC_ALL=C
-export LC_ALL
-${CPP:-cpp} "$@" -DXorgLoader sdksyms.c | ${AWK:-awk} -v topdir=$topdir '
-BEGIN {
- sdk = 0;
- print("/*");
- print(" * These symbols are referenced to ensure they");
- print(" * will be available in the X Server binary.");
- print(" */");
- printf("/* topdir=%s */\n", topdir);
- print("_X_HIDDEN void *xorg_symbols[] = {");
-
- printf("sdksyms.c:") > "sdksyms.dep";
-}
-/^# [0-9]+ "/ {
- # Process text after a include in a relative path or when the
- # processed file has a basename matching $top_srcdir.
- # Note that indexing starts at 1; 0 means no match, and there
- # is a starting ".
- sdk = $3 !~ /^"\// || index($3, topdir) == 2;
-
- if (sdk && $3 ~ /\.h"$/) {
- # remove quotes
- gsub(/"/, "", $3);
- line = $2;
- header = $3;
- if (! headers[$3]) {
- printf(" \\\n %s", $3) >> "sdksyms.dep";
- headers[$3] = 1;
- }
- }
- next;
-}
-
-/^extern[ ]/ {
- if (sdk) {
- n = 3;
-
- # skip attribute, if any
- while ($n ~ /^(__attribute__|__global)/ ||
- # skip modifiers, if any
- $n ~ /^\*?(unsigned|const|volatile|struct)$/ ||
- # skip pointer
- $n ~ /^[a-zA-Z0-9_]*\*$/)
- n++;
-
- # type specifier may not be set, as in
- # extern _X_EXPORT unsigned name(...)
- if ($n !~ /[^a-zA-Z0-9_]/)
- n++;
-
- # go back if we are at the parameter list already
- if ($n ~ /^[(]([^*].*)?$/)
- n--;
-
- # match
- # extern _X_EXPORT type (* name[])(...)
- if ($n ~ /^[^a-zA-Z0-9_]+$/)
- n++;
-
- # match
- # extern _X_EXPORT const name *const ...
- if ($n ~ /^([^a-zA-Z0-9_]+)?const$/)
- n++;
-
- # actual name may be in the next line, as in
- # extern _X_EXPORT type
- # possibly ending with a *
- # name(...)
- if ($n == "" || $n ~ /^\*+$/) {
- getline;
- n = 1;
- }
-
- # dont modify $0 or $n
- symbol = $n;
-
- # remove starting non word chars
- sub(/^[^a-zA-Z0-9_]+/, "",symbol);
-
- # remove from first non word to end of line
- sub(/[^a-zA-Z0-9_].*/, "", symbol);
-
- #print;
- printf(" (void *) &%-50s /* %s:%s */\n", symbol ",", header, line);
- }
-}
-
-{
- line++;
-}
-
-END {
- print("};");
-
- print("") >> "sdksyms.dep";
-}' > _sdksyms.c
-
-STATUS=$?
-
-cat _sdksyms.c >> sdksyms.c
-rm _sdksyms.c
-
-[ $? != 0 ] && exit $?
-
-exit $STATUS
+#!/bin/sh
+
+cat > sdksyms.c << EOF
+/* This file is automatically generated by sdksyms.sh. */
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+
+/* These must be included first */
+#include "misc.h"
+#include "miscstruct.h"
+
+
+/* render/Makefile.am */
+#include "picture.h"
+#include "mipict.h"
+#include "glyphstr.h"
+#include "picturestr.h"
+
+
+/* fb/Makefile.am -- module */
+/*
+#include "fb.h"
+#include "fbrop.h"
+#include "fboverlay.h"
+#include "wfbrename.h"
+#include "fbpict.h"
+ */
+
+
+/* miext/shadow/Makefile.am -- module */
+/*
+#include "shadow.h"
+ */
+
+
+/* miext/damage/Makefile.am */
+#include "damage.h"
+#include "damagestr.h"
+
+/* miext/sync/Makefile.am */
+#include "misync.h"
+#include "misyncstr.h"
+
+/* Xext/Makefile.am -- half is module, half is builtin */
+/*
+#include "xvdix.h"
+#include "xvmcext.h"
+ */
+#include "geext.h"
+#include "geint.h"
+#include "shmint.h"
+#include "syncsdk.h"
+#if XINERAMA
+# include "panoramiXsrv.h"
+# include "panoramiX.h"
+#endif
+
+
+/* hw/xfree86/int10/Makefile.am -- module */
+/*
+#include "xf86int10.h"
+ */
+
+
+/* hw/xfree86/i2c/Makefile.am -- "mostly" modules */
+#include "xf86i2c.h"
+/*
+#include "bt829.h"
+#include "fi1236.h"
+#include "msp3430.h"
+#include "tda8425.h"
+#include "tda9850.h"
+#include "tda9885.h"
+#include "uda1380.h"
+#include "i2c_def.h"
+ */
+
+
+/* hw/xfree86/modes/Makefile.am */
+#include "xf86Crtc.h"
+#include "xf86Modes.h"
+#include "xf86RandR12.h"
+/* #include "xf86Rename.h" */
+
+
+/* hw/xfree86/ddc/Makefile.am */
+#include "edid.h"
+#include "xf86DDC.h"
+
+
+/* hw/xfree86/dri2/Makefile.am -- module */
+/*
+#if DRI2
+# include "dri2.h"
+#endif
+ */
+
+
+/* hw/xfree86/vgahw/Makefile.am -- module */
+/*
+#include "vgaHW.h"
+ */
+
+
+/* hw/xfree86/fbdevhw/Makefile.am -- module */
+/*
+#include "fbdevhw.h"
+ */
+
+
+/* hw/xfree86/common/Makefile.am */
+#include "compiler.h"
+#include "fourcc.h"
+#include "xf86.h"
+#include "xf86Module.h"
+#include "xf86Opt.h"
+#include "xf86PciInfo.h"
+#include "xf86Priv.h"
+#include "xf86Privstr.h"
+#include "xf86cmap.h"
+#include "xf86fbman.h"
+#include "xf86str.h"
+#include "xf86Xinput.h"
+#include "xf86VGAarbiter.h"
+#include "xisb.h"
+#if XV
+# include "xf86xv.h"
+# include "xf86xvmc.h"
+# include "xf86xvpriv.h"
+#endif
+/* XF86VidMode code is in libextmod module */
+/*
+#if XF86VIDMODE
+# include "vidmodeproc.h"
+#endif
+ */
+#include "xorgVersion.h"
+#if defined(__sparc__) || defined(__sparc)
+# include "xf86sbusBus.h"
+#endif
+
+
+/* hw/xfree86/ramdac/Makefile.am */
+#include "BT.h"
+#include "IBM.h"
+#include "TI.h"
+#include "xf86Cursor.h"
+#include "xf86RamDac.h"
+
+
+/* hw/xfree86/shadowfb/Makefile.am -- module */
+/*
+#include "shadowfb.h"
+ */
+
+
+/* hw/xfree86/os-support/solaris/Makefile.am */
+#if defined(sun386)
+# include "agpgart.h"
+#endif
+
+
+/* hw/xfree86/os-support/Makefile.am */
+#include "xf86_OSproc.h"
+#include "xf86_OSlib.h"
+
+
+/* hw/xfree86/os-support/bus/Makefile.am */
+#include "xf86Pci.h"
+#if defined(__sparc__) || defined(__sparc)
+# include "xf86Sbus.h"
+#endif
+
+
+/* hw/xfree86/xaa/Makefile.am -- module */
+/*
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaarop.h"
+ */
+
+
+/* hw/xfree86/dixmods/extmod/Makefile.am -- module */
+/*
+#include "dgaproc.h"
+ */
+
+
+/* hw/xfree86/parser/Makefile.am */
+#include "xf86Parser.h"
+#include "xf86Optrec.h"
+
+
+/* hw/xfree86/vbe/Makefile.am -- module */
+/*
+#include "vbe.h"
+#include "vbeModes.h"
+ */
+
+
+/* hw/xfree86/dri/Makefile.am -- module */
+/*
+#if XF86DRI
+# include "dri.h"
+# include "sarea.h"
+# include "dristruct.h"
+#endif
+ */
+
+
+/* mi/Makefile.am */
+#include "micmap.h"
+#include "miline.h"
+#include "mipointer.h"
+#include "mi.h"
+#include "mibstore.h"
+#include "migc.h"
+#include "mipointrst.h"
+#include "mizerarc.h"
+#include "micoord.h"
+#include "mifillarc.h"
+#include "mispans.h"
+#include "miwideline.h"
+#include "mistruct.h"
+#include "mifpoly.h"
+#include "mioverlay.h"
+
+
+/* randr/Makefile.am */
+#include "randrstr.h"
+#include "rrtransform.h"
+
+
+/* dbe/Makefile.am -- module */
+/*
+#include "dbestruct.h"
+ */
+
+
+/* exa/Makefile.am -- module */
+/*
+#include "exa.h"
+ */
+
+
+/* xfixes/Makefile.am */
+#include "xfixes.h"
+
+
+/* include/Makefile.am */
+#include "XIstubs.h"
+#include "Xprintf.h"
+#include "closestr.h"
+#include "closure.h"
+#include "colormap.h"
+#include "colormapst.h"
+#include "hotplug.h"
+#include "client.h"
+#include "cursor.h"
+#include "cursorstr.h"
+#include "dix.h"
+#include "dixaccess.h"
+#include "dixevents.h"
+#include "dixfont.h"
+#include "dixfontstr.h"
+#include "dixgrabs.h"
+#include "dixstruct.h"
+#include "exevents.h"
+#include "extension.h"
+#include "extinit.h"
+#include "extnsionst.h"
+#include "gc.h"
+#include "gcstruct.h"
+#include "globals.h"
+#include "input.h"
+#include "inputstr.h"
+/* already included */
+/*
+#include "misc.h"
+#include "miscstruct.h"
+ */
+#include "opaque.h"
+#include "os.h"
+#include "pixmap.h"
+#include "pixmapstr.h"
+#include "privates.h"
+#include "property.h"
+#include "propertyst.h"
+#include "ptrveloc.h"
+#include "region.h"
+#include "regionstr.h"
+#include "registry.h"
+#include "resource.h"
+#include "rgb.h"
+#include "screenint.h"
+#include "scrnintstr.h"
+#include "selection.h"
+#include "servermd.h"
+#include "site.h"
+#include "swaprep.h"
+#include "swapreq.h"
+#include "validate.h"
+#include "window.h"
+#include "windowstr.h"
+#include "xace.h"
+#include "xkbfile.h"
+#include "xkbsrv.h"
+#include "xkbstr.h"
+#include "xkbrules.h"
+#include "xserver-properties.h"
+
+EOF
+
+topdir=$1
+shift
+LC_ALL=C
+export LC_ALL
+${CPP:-cpp} "$@" -DXorgLoader sdksyms.c | ${AWK:-awk} -v topdir=$topdir '
+BEGIN {
+ sdk = 0;
+ print("/*");
+ print(" * These symbols are referenced to ensure they");
+ print(" * will be available in the X Server binary.");
+ print(" */");
+ printf("/* topdir=%s */\n", topdir);
+ print("_X_HIDDEN void *xorg_symbols[] = {");
+
+ printf("sdksyms.c:") > "sdksyms.dep";
+}
+/^# [0-9]+ "/ {
+ # Process text after a include in a relative path or when the
+ # processed file has a basename matching $top_srcdir.
+ # Note that indexing starts at 1; 0 means no match, and there
+ # is a starting ".
+ sdk = $3 !~ /^"\// || index($3, topdir) == 2;
+
+ if (sdk && $3 ~ /\.h"$/) {
+ # remove quotes
+ gsub(/"/, "", $3);
+ line = $2;
+ header = $3;
+ if (! headers[$3]) {
+ printf(" \\\n %s", $3) >> "sdksyms.dep";
+ headers[$3] = 1;
+ }
+ }
+ next;
+}
+
+/^extern[ ]/ {
+ if (sdk) {
+ n = 3;
+
+ # skip attribute, if any
+ while ($n ~ /^(__attribute__|__global)/ ||
+ # skip modifiers, if any
+ $n ~ /^\*?(unsigned|const|volatile|struct)$/ ||
+ # skip pointer
+ $n ~ /^[a-zA-Z0-9_]*\*$/)
+ n++;
+
+ # type specifier may not be set, as in
+ # extern _X_EXPORT unsigned name(...)
+ if ($n !~ /[^a-zA-Z0-9_]/)
+ n++;
+
+ # go back if we are at the parameter list already
+ if ($n ~ /^[(]([^*].*)?$/)
+ n--;
+
+ # match
+ # extern _X_EXPORT type (* name[])(...)
+ if ($n ~ /^[^a-zA-Z0-9_]+$/)
+ n++;
+
+ # match
+ # extern _X_EXPORT const name *const ...
+ if ($n ~ /^([^a-zA-Z0-9_]+)?const$/)
+ n++;
+
+ # actual name may be in the next line, as in
+ # extern _X_EXPORT type
+ # possibly ending with a *
+ # name(...)
+ if ($n == "" || $n ~ /^\*+$/) {
+ getline;
+ n = 1;
+ }
+
+ # dont modify $0 or $n
+ symbol = $n;
+
+ # remove starting non word chars
+ sub(/^[^a-zA-Z0-9_]+/, "",symbol);
+
+ # remove from first non word to end of line
+ sub(/[^a-zA-Z0-9_].*/, "", symbol);
+
+ #print;
+ printf(" (void *) &%-50s /* %s:%s */\n", symbol ",", header, line);
+ }
+}
+
+{
+ line++;
+}
+
+END {
+ print("};");
+
+ print("") >> "sdksyms.dep";
+}' > _sdksyms.c
+
+STATUS=$?
+
+cat _sdksyms.c >> sdksyms.c
+rm _sdksyms.c
+
+[ $? != 0 ] && exit $?
+
+exit $STATUS
diff --git a/xorg-server/hw/xfree86/man/xorg.conf.man b/xorg-server/hw/xfree86/man/xorg.conf.man
index 4bec31695..ce0c177bc 100644
--- a/xorg-server/hw/xfree86/man/xorg.conf.man
+++ b/xorg-server/hw/xfree86/man/xorg.conf.man
@@ -1,2485 +1,2485 @@
-.\" shorthand for double quote that works everywhere.
-.ds q \N'34'
-.TH __xconfigfile__ __filemansuffix__ __vendorversion__
-.SH NAME
-__xconfigfile__ and __xconfigdir__ \- configuration files for
-__xservername__ X server
-.SH INTRODUCTION
-.B __xservername__
-supports several mechanisms for supplying/obtaining configuration and
-run-time parameters: command line options, environment variables, the
-__xconfigfile__ and __xconfigdir__ configuration files, auto-detection,
-and fallback defaults. When the same information is supplied in more
-than one way, the highest precedence mechanism is used. The list of
-mechanisms is ordered from highest precedence to lowest. Note that not
-all parameters can be supplied via all methods. The available command
-line options and environment variables (and some defaults) are
-described in the Xserver(__appmansuffix__) and
-__xservername__(__appmansuffix__) manual pages. Most configuration file
-parameters, with their defaults, are described below. Driver and module
-specific configuration parameters are described in the relevant driver
-or module manual page.
-.SH DESCRIPTION
-.B __xservername__
-uses a configuration file called
-.I __xconfigfile__
-and files ending in the suffix
-.I .conf
-from the directory
-.I __xconfigdir__
-for its initial setup.
-The
-.I __xconfigfile__
-configuration file is searched for in the following places when the
-server is started as a normal user:
-.PP
-.RS 4
-.nf
-.IR /etc/X11/ <cmdline>
-.IR __projectroot__/etc/X11/ <cmdline>
-.IB /etc/X11/ $XORGCONFIG
-.IB __projectroot__/etc/X11/ $XORGCONFIG
-.I /etc/X11/__xconfigfile__
-.I /etc/__xconfigfile__
-.IR __projectroot__/etc/X11/__xconfigfile__. <hostname>
-.I __projectroot__/etc/X11/__xconfigfile__
-.IR __projectroot__/lib/X11/__xconfigfile__. <hostname>
-.I __projectroot__/lib/X11/__xconfigfile__
-.fi
-.RE
-.PP
-where
-.I <cmdline>
-is a relative path (with no \(lq..\(rq components) specified with the
-.B \-config
-command line option,
-.B $XORGCONFIG
-is the relative path (with no \(lq..\(rq components) specified by that
-environment variable, and
-.I <hostname>
-is the machine's hostname as reported by
-.BR gethostname (__libmansuffix__).
-.PP
-When the __xservername__ server is started by the \(lqroot\(rq user, the config file
-search locations are as follows:
-.PP
-.RS 4
-.nf
-<cmdline>
-.IR /etc/X11/ <cmdline>
-.IR __projectroot__/etc/X11/ <cmdline>
-.B $XORGCONFIG
-.IB /etc/X11/ $XORGCONFIG
-.IB __projectroot__/etc/X11/ $XORGCONFIG
-.I /etc/X11/__xconfigfile__
-.I /etc/__xconfigfile__
-.IR __projectroot__/etc/X11/__xconfigfile__. <hostname>
-.I __projectroot__/etc/X11/__xconfigfile__
-.IR __projectroot__/lib/X11/__xconfigfile__. <hostname>
-.I __projectroot__/lib/X11/__xconfigfile__
-.fi
-.RE
-.PP
-where
-.I <cmdline>
-is the path specified with the
-.B \-config
-command line option (which may be absolute or relative),
-.B $XORGCONFIG
-is the path specified by that
-environment variable (absolute or relative),
-.B $HOME
-is the path specified by that environment variable (usually the home
-directory), and
-.I <hostname>
-is the machine's hostname as reported by
-.BR gethostname (__libmansuffix__).
-.PP
-Additional configuration files are searched for in the following
-directories when the server is started as a normal user:
-.PP
-.RS 4
-.nf
-.IR /etc/X11/ <cmdline>
-.IR __sysconfdir__/X11/ <cmdline>
-.I /etc/X11/__xconfigdir__
-.I __sysconfdir__/X11/__xconfigdir__
-.fi
-.RE
-.PP
-where
-.I <cmdline>
-is a relative path (with no \(lq..\(rq components) specified with the
-.B \-configdir
-command line option.
-.PP
-When the __xservername__ server is started by the \(lqroot\(rq user, the
-config directory search locations are as follows:
-.PP
-.RS 4
-.nf
-<cmdline>
-.IR /etc/X11/ <cmdline>
-.IR __sysconfdir__/X11/ <cmdline>
-.I /etc/X11/__xconfigdir__
-.I __sysconfdir__/X11/__xconfigdir__
-.fi
-.RE
-.PP
-where
-.I <cmdline>
-is the path specified with the
-.B \-configdir
-command line option (which may be absolute or relative).
-.PP
-Finally, configuration files will also be searched for in directories
-reserved for system use. These are to separate configuration files from
-the vendor or 3rd party packages from those of local administration.
-These files are found in the following directories:
-.PP
-.RS 4
-.nf
-.I /usr/share/X11/__xconfigdir__
-.I __datadir__/X11/__xconfigdir__
-.fi
-.RE
-.PP
-The
-.I __xconfigfile__
-and
-.I __xconfigdir__
-files are composed of a number of sections which may be present in any order,
-or omitted to use default configuration values.
-Each section has the form:
-.PP
-.RS 4
-.nf
-.BI "Section \*q" SectionName \*q
-.RI " " SectionEntry
- ...
-.B EndSection
-.fi
-.RE
-.PP
-The section names are:
-.PP
-.RS 4
-.nf
-.BR "Files " "File pathnames"
-.BR "ServerFlags " "Server flags"
-.BR "Module " "Dynamic module loading"
-.BR "Extensions " "Extension enabling"
-.BR "InputDevice " "Input device description"
-.BR "InputClass " "Input class description"
-.BR "Device " "Graphics device description"
-.BR "VideoAdaptor " "Xv video adaptor description"
-.BR "Monitor " "Monitor description"
-.BR "Modes " "Video modes descriptions"
-.BR "Screen " "Screen configuration"
-.BR "ServerLayout " "Overall layout"
-.BR "DRI " "DRI\-specific configuration"
-.BR "Vendor " "Vendor\-specific configuration"
-.fi
-.RE
-.PP
-The following obsolete section names are still recognised for compatibility
-purposes.
-In new config files, the
-.B InputDevice
-section should be used instead.
-.PP
-.RS 4
-.nf
-.BR "Keyboard " "Keyboard configuration"
-.BR "Pointer " "Pointer/mouse configuration"
-.fi
-.RE
-.PP
-The old
-.B XInput
-section is no longer recognised.
-.PP
-The
-.B ServerLayout
-sections are at the highest level.
-They bind together the input and output devices that will be used in a session.
-The input devices are described in the
-.B InputDevice
-sections.
-Output devices usually consist of multiple independent components (e.g.,
-a graphics board and a monitor).
-These multiple components are bound together in the
-.B Screen
-sections, and it is these that are referenced by the
-.B ServerLayout
-section.
-Each
-.B Screen
-section binds together a graphics board and a monitor.
-The graphics boards are described in the
-.B Device
-sections, and the monitors are described in the
-.B Monitor
-sections.
-.PP
-Config file keywords are case\-insensitive, and \(lq_\(rq characters are
-ignored.
-Most strings (including
-.B Option
-names) are also case-insensitive, and insensitive to white space and
-\(lq_\(rq characters.
-.PP
-Each config file entry usually takes up a single line in the file. They
-consist of a keyword, which is possibly followed by one or more arguments,
-with the number and types of the arguments depending on the keyword.
-The argument types are:
-.PP
-.RS 4
-.nf
-.BR "Integer " "an integer number in decimal, hex or octal"
-.BR "Real " "a floating point number"
-.BR "String " "a string enclosed in double quote marks (\*q)"
-.fi
-.RE
-.PP
-Note: hex integer values must be prefixed with \(lq0x\(rq, and octal values
-with \(lq0\(rq.
-.PP
-A special keyword called
-.B Option
-may be used to provide free\-form data to various components of the server.
-The
-.B Option
-keyword takes either one or two string arguments.
-The first is the option name, and the optional second argument is the
-option value.
-Some commonly used option value types include:
-.PP
-.RS 4
-.nf
-.BR "Integer " "an integer number in decimal, hex or octal"
-.BR "Real " "a floating point number"
-.BR "String " "a sequence of characters"
-.BR "Boolean " "a boolean value (see below)"
-.BR "Frequency " "a frequency value (see below)"
-.fi
-.RE
-.PP
-Note that
-.I all
-.B Option
-values, not just strings, must be enclosed in quotes.
-.PP
-Boolean options may optionally have a value specified.
-When no value is specified, the option's value is
-.BR TRUE .
-The following boolean option values are recognised as
-.BR TRUE :
-.PP
-.RS 4
-.BR 1 ,
-.BR on ,
-.BR true ,
-.B yes
-.RE
-.PP
-and the following boolean option values are recognised as
-.BR FALSE :
-.PP
-.RS 4
-.BR 0 ,
-.BR off ,
-.BR false ,
-.B no
-.RE
-.PP
-If an option name is prefixed with
-.RB \*q No \*q,
-then the option value is negated.
-.PP
-Example: the following option entries are equivalent:
-.PP
-.RS 4
-.nf
-.B "Option \*qAccel\*q \*qOff\*q"
-.B "Option \*qNoAccel\*q"
-.B "Option \*qNoAccel\*q \*qOn\*q"
-.B "Option \*qAccel\*q \*qfalse\*q"
-.B "Option \*qAccel\*q \*qno\*q"
-.fi
-.RE
-.PP
-Frequency option values consist of a real number that is optionally
-followed by one of the following frequency units:
-.PP
-.RS 4
-.BR Hz ,
-.BR k ,
-.BR kHz ,
-.BR M ,
-.B MHz
-.RE
-.PP
-When the unit name is omitted, the correct units will be determined from
-the value and the expectations of the appropriate range of the value.
-It is recommended that the units always be specified when using frequency
-option values to avoid any errors in determining the value.
-.SH "FILES SECTION"
-The
-.B Files
-section is used to specify some path names required by the server.
-Some of these paths can also be set from the command line (see
-.BR Xserver (__appmansuffix__)
-and
-.BR __xservername__ (__appmansuffix__)).
-The command line settings override the values specified in the config
-file.
-The
-.B Files
-section is optional, as are all of the entries that may appear in it.
-.PP
-The entries that can appear in this section are:
-.TP 7
-.BI "FontPath \*q" path \*q
-sets the search path for fonts.
-This path is a comma separated list of font path elements which the __xservername__
-server searches for font databases.
-Multiple
-.B FontPath
-entries may be specified, and they will be concatenated to build up the
-fontpath used by the server. Font path elements can be absolute
-directory paths, catalogue directories or a font server identifier. The
-formats of the later two are explained below:
-.PP
-.RS 7
-Catalogue directories:
-.PP
-.RS 4
-Catalogue directories can be specified using the prefix \fBcatalogue:\fR
-before the directory name. The directory can then be populated with
-symlinks pointing to the real font directories, using the following
-syntax in the symlink name:
-.PP
-.RS 4
-.IR <identifier> : [attribute]: pri= <priority>
-.RE
-.PP
-where
-.I <identifier>
-is an alphanumeric identifier,
-.I [attribute]
-is an attribute which will be passed to the underlying FPE and
-.I <priority>
-is a number used to order the fontfile FPEs. Examples:
-.PP
-.RS 4
-.nf
-.I 75dpi:unscaled:pri=20 -> /usr/share/X11/fonts/75dpi
-.I gscript:pri=60 -> /usr/share/fonts/default/ghostscript
-.I misc:unscaled:pri=10 \-> /usr/share/X11/fonts/misc
-.fi
-.PP
-.RE .RE .RE
-.PP
-.RS 7
-Font server identifiers:
-.PP
-.RS 4
-Font server identifiers have the form:
-.RS 4
-.PP
-.IR <trans> / <hostname> : <port\-number>
-.RE
-.PP
-where
-.I <trans>
-is the transport type to use to connect to the font server (e.g.,
-.B unix
-for UNIX\-domain sockets or
-.B tcp
-for a TCP/IP connection),
-.I <hostname>
-is the hostname of the machine running the font server, and
-.I <port\-number>
-is the port number that the font server is listening on (usually 7100).
-.RE
-.PP
-When this entry is not specified in the config file, the server falls back
-to the compiled\-in default font path, which contains the following
-font path elements (which can be set inside a catalogue directory):
-.PP
-.RS 4
-.nf
-.I __datadir__/fonts/X11/misc/
-.I __datadir__/fonts/X11/TTF/
-.I __datadir__/fonts/X11/OTF/
-.I __datadir__/fonts/X11/Type1/
-.I __datadir__/fonts/X11/100dpi/
-.I __datadir__/fonts/X11/75dpi/
-.fi
-.RE
-.PP
-Font path elements that are found to be invalid are removed from the
-font path when the server starts up.
-.RE
-.TP 7
-.BI "ModulePath \*q" path \*q
-sets the search path for loadable __xservername__ server modules.
-This path is a comma separated list of directories which the __xservername__ server
-searches for loadable modules loading in the order specified.
-Multiple
-.B ModulePath
-entries may be specified, and they will be concatenated to build the
-module search path used by the server. The default module path is
-.PP
-.RS 11
-__modulepath__
-.RE
-.\" The LogFile keyword is not currently implemented
-.ig
-.TP 7
-.BI "LogFile \*q" path \*q
-sets the name of the __xservername__ server log file.
-The default log file name is
-.PP
-.RS 11
-.RI __logdir__/__xservername__. <n> .log
-.RE
-.PP
-.RS 7
-where
-.I <n>
-is the display number for the __xservername__ server.
-..
-.TP 7
-.BI "XkbDir \*q" path \*q
-sets the base directory for keyboard layout files. The
-.B \-xkbdir
-command line option can be used to override this. The default directory is
-.PP
-.RS 11
-__xkbdir__
-.RE
-.SH "SERVERFLAGS SECTION"
-In addition to options specific to this section (described below), the
-.B ServerFlags
-section is used to specify some global
-__xservername__ server options.
-All of the entries in this section are
-.BR Options ,
-although for compatibility purposes some of the old style entries are
-still recognised.
-Those old style entries are not documented here, and using them is
-discouraged.
-The
-.B ServerFlags
-section is optional, as are the entries that may be specified in it.
-.PP
-.B Options
-specified in this section (with the exception of the
-.B \*qDefaultServerLayout\*q
-.BR Option )
-may be overridden by
-.B Options
-specified in the active
-.B ServerLayout
-section.
-Options with command line equivalents are overridden when their command
-line equivalent is used.
-The options recognised by this section are:
-.TP 7
-.BI "Option \*qDefaultServerLayout\*q \*q" layout\-id \*q
-This specifies the default
-.B ServerLayout
-section to use in the absence of the
-.B \-layout
-command line option.
-.TP 7
-.BI "Option \*qNoTrapSignals\*q \*q" boolean \*q
-This prevents the __xservername__ server from trapping a range of unexpected fatal
-signals and exiting cleanly.
-Instead, the __xservername__ server will die and drop core where the fault occurred.
-The default behaviour is for the __xservername__ server to exit cleanly, but still drop a
-core file.
-In general you never want to use this option unless you are debugging an __xservername__
-server problem and know how to deal with the consequences.
-.TP 7
-.BI "Option \*qUseSIGIO\*q \*q" boolean \*q
-This controls whether the __xservername__ server requests that events from
-input devices be reported via a SIGIO signal handler (also known as SIGPOLL
-on some platforms), or only reported via the standard select(3) loop.
-The default behaviour is platform specific. In general you do not want to
-use this option unless you are debugging the __xservername__ server, or
-working around a specific bug until it is fixed, and understand the
-consequences.
-.TP 7
-.BI "Option \*qDontVTSwitch\*q \*q" boolean \*q
-This disallows the use of the
-.BI Ctrl+Alt+F n
-sequence (where
-.RI F n
-refers to one of the numbered function keys).
-That sequence is normally used to switch to another \*qvirtual terminal\*q
-on operating systems that have this feature.
-When this option is enabled, that key sequence has no special meaning and
-is passed to clients.
-Default: off.
-.TP 7
-.BI "Option \*qDontZap\*q \*q" boolean \*q
-This disallows the use of the
-.B Terminate_Server
-XKB action (usually on Ctrl+Alt+Backspace, depending on XKB options).
-This action is normally used to terminate the __xservername__ server.
-When this option is enabled, the action has no effect.
-Default: off.
-.TP 7
-.BI "Option \*qDontZoom\*q \*q" boolean \*q
-This disallows the use of the
-.B Ctrl+Alt+Keypad\-Plus
-and
-.B Ctrl+Alt+Keypad\-Minus
-sequences.
-These sequences allows you to switch between video modes.
-When this option is enabled, those key sequences have no special meaning
-and are passed to clients.
-Default: off.
-.TP 7
-.BI "Option \*qDisableVidModeExtension\*q \*q" boolean \*q
-This disables the parts of the VidMode extension used by the xvidtune client
-that can be used to change the video modes.
-Default: the VidMode extension is enabled.
-.TP 7
-.BI "Option \*qAllowNonLocalXvidtune\*q \*q" boolean \*q
-This allows the xvidtune client (and other clients that use the VidMode
-extension) to connect from another host.
-Default: off.
-.TP 7
-.BI "Option \*qAllowMouseOpenFail\*q \*q" boolean \*q
-This tells the mousedrv(__drivermansuffix__) and vmmouse(__drivermansuffix__)
-drivers to not report failure if the mouse device can't be opened/initialised.
-It has no effect on the evdev(__drivermansuffix__) or other drivers.
-Default: false.
-.TP 7
-.BI "Option \*qVTSysReq\*q \*q" boolean \*q
-enables the SYSV\-style VT switch sequence for non\-SYSV systems
-which support VT switching.
-This sequence is
-.B Alt\-SysRq
-followed by a function key
-.RB ( Fn ).
-This prevents the __xservername__ server trapping the
-keys used for the default VT switch sequence, which means that clients can
-access them.
-Default: off.
-.TP 7
-.BI "Option \*qBlankTime\*q \*q" time \*q
-sets the inactivity timeout for the
-.B blank
-phase of the screensaver.
-.I time
-is in minutes.
-This is equivalent to the __xservername__ server's
-.B \-s
-flag, and the value can be changed at run\-time with
-.BR xset(__appmansuffix__).
-Default: 10 minutes.
-.TP 7
-.BI "Option \*qStandbyTime\*q \*q" time \*q
-sets the inactivity timeout for the
-.B standby
-phase of DPMS mode.
-.I time
-is in minutes, and the value can be changed at run\-time with
-.BR xset(__appmansuffix__).
-Default: 10 minutes.
-This is only suitable for VESA DPMS compatible monitors, and may not be
-supported by all video drivers.
-It is only enabled for screens that have the
-.B \*qDPMS\*q
-option set (see the MONITOR section below).
-.TP 7
-.BI "Option \*qSuspendTime\*q \*q" time \*q
-sets the inactivity timeout for the
-.B suspend
-phase of DPMS mode.
-.I time
-is in minutes, and the value can be changed at run\-time with
-.BR xset(__appmansuffix__).
-Default: 10 minutes.
-This is only suitable for VESA DPMS compatible monitors, and may not be
-supported by all video drivers.
-It is only enabled for screens that have the
-.B \*qDPMS\*q
-option set (see the MONITOR section below).
-.TP 7
-.BI "Option \*qOffTime\*q \*q" time \*q
-sets the inactivity timeout for the
-.B off
-phase of DPMS mode.
-.I time
-is in minutes, and the value can be changed at run\-time with
-.BR xset(__appmansuffix__).
-Default: 10 minutes.
-This is only suitable for VESA DPMS compatible monitors, and may not be
-supported by all video drivers.
-It is only enabled for screens that have the
-.B \*qDPMS\*q
-option set (see the MONITOR section below).
-.TP 7
-.BI "Option \*qPixmap\*q \*q" bpp \*q
-This sets the pixmap format to use for depth 24.
-Allowed values for
-.I bpp
-are 24 and 32.
-Default: 32 unless driver constraints don't allow this (which is rare).
-Note: some clients don't behave well when this value is set to 24.
-.TP 7
-.BI "Option \*qPC98\*q \*q" boolean \*q
-Specify that the machine is a Japanese PC\-98 machine.
-This should not be enabled for anything other than the Japanese\-specific
-PC\-98 architecture.
-Default: auto\-detected.
-.TP 7
-.BI "Option \*qNoPM\*q \*q" boolean \*q
-Disables something to do with power management events.
-Default: PM enabled on platforms that support it.
-.TP 7
-.BI "Option \*qXinerama\*q \*q" boolean \*q
-enable or disable XINERAMA extension.
-Default is disabled.
-.TP 7
-.BI "Option \*qAIGLX\*q \*q" boolean \*q
-enable or disable AIGLX. AIGLX is enabled by default.
-.TP 7
-.BI "Option \*qDRI2\*q \*q" boolean \*q
-enable or disable DRI2. DRI2 is disabled by default.
-.TP 7
-.BI "Option \*qGlxVisuals\*q \*q" string \*q
-This option controls how many GLX visuals the GLX modules sets up.
-The default value is
-.BR "typical" ,
-which will setup up a typical subset of
-the GLXFBConfigs provided by the driver as GLX visuals. Other options are
-.BR "minimal" ,
-which will set up the minimal set allowed by the GLX specification and
-.BR "all"
-which will setup GLX visuals for all GLXFBConfigs.
-.TP 7
-.BI "Option \*qUseDefaultFontPath\*q \*q" boolean \*q
-Include the default font path even if other paths are specified in
-xorg.conf. If enabled, other font paths are included as well. Enabled by
-default.
-.TP 7
-.BI "Option \*qIgnoreABI\*q \*q" boolean \*q
-Allow modules built for a different, potentially incompatible version of
-the X server to load. Disabled by default.
-.TP 7
-.BI "Option \*qAutoAddDevices\*q \*q" boolean \*q
-If this option is disabled, then no devices will be added from HAL events.
-Enabled by default.
-.TP 7
-.BI "Option \*qAutoEnableDevices\*q \*q" boolean \*q
-If this option is disabled, then the devices will be added (and the
-DevicePresenceNotify event sent), but not enabled, thus leaving policy up
-to the client.
-Enabled by default.
-.TP 7
-.BI "Option \*qLog\*q \*q" string \*q
-This option controls whether the log is flushed and/or synced to disk after
-each message.
-Possible values are
-.B flush
-or
-.BR sync .
-Unset by default.
-.SH "MODULE SECTION"
-The
-.B Module
-section is used to specify which __xservername__ server modules should be loaded.
-This section is ignored when the __xservername__ server is built in static form.
-The type of modules normally loaded in this section are __xservername__ server
-extension modules.
-Most other module types are loaded automatically when they are needed via
-other mechanisms.
-The
-.B Module
-section is optional, as are all of the entries that may be specified in
-it.
-.PP
-Entries in this section may be in two forms.
-The first and most commonly used form is an entry that uses the
-.B Load
-keyword, as described here:
-.TP 7
-.BI "Load \*q" modulename \*q
-This instructs the server to load the module called
-.IR modulename .
-The module name given should be the module's standard name, not the
-module file name.
-The standard name is case\-sensitive, and does not include the \(lqlib\(rq
-prefix, or the \(lq.a\(rq, \(lq.o\(rq, or \(lq.so\(rq suffixes.
-.PP
-.RS 7
-Example: the DRI extension module can be loaded with the following entry:
-.PP
-.RS 4
-.B "Load \*qdri\*q"
-.RE
-.RE
-.TP 7
-.BI "Disable \*q" modulename \*q
-This instructs the server to not load the module called
-.IR modulename .
-Some modules are loaded by default in the server, and this overrides that
-default. If a
-.B Load
-instruction is given for the same module, it overrides the
-.B Disable
-instruction and the module is loaded. The module name given should be the
-module's standard name, not the module file name. As with the
-.B Load
-instruction, the standard name is case-sensitive, and does not include the
-"lib" prefix, or the ".a", ".o", or ".so" suffixes.
-.PP
-The second form of entry is a
-.BR SubSection,
-with the subsection name being the module name, and the contents of the
-.B SubSection
-being
-.B Options
-that are passed to the module when it is loaded.
-.PP
-Example: the extmod module (which contains a miscellaneous group of
-server extensions) can be loaded, with the XFree86\-DGA extension
-disabled by using the following entry:
-.PP
-.RS 4
-.nf
-.B "SubSection \*qextmod\*q"
-.B " Option \*qomit XFree86\-DGA\*q"
-.B EndSubSection
-.fi
-.RE
-.PP
-Modules are searched for in each directory specified in the
-.B ModulePath
-search path, and in the drivers, extensions, input, internal, and
-multimedia subdirectories of each of those directories.
-In addition to this, operating system specific subdirectories of all
-the above are searched first if they exist.
-.PP
-To see what extension modules are available, check the extensions
-subdirectory under:
-.PP
-.RS 4
-.nf
-__modulepath__
-.fi
-.RE
-.PP
-The \(lqextmod\(rq, \(lqdbe\(rq, \(lqdri\(rq, \(lqdri2\(rq, \(lqglx\(rq,
-and \(lqrecord\(rq extension modules are loaded automatically, if they
-are present, unless disabled with \*qDisable\*q entries.
-It is recommended
-that at very least the \(lqextmod\(rq extension module be loaded.
-If it isn't, some commonly used server extensions (like the SHAPE
-extension) will not be available.
-.SH "EXTENSIONS SECTION"
-The
-.B Extensions
-section is used to specify which X11 protocol extensions should be enabled
-or disabled.
-The
-.B Extensions
-section is optional, as are all of the entries that may be specified in
-it.
-.PP
-Entries in this section are listed as Option statements with the name of
-the extension as the first argument, and a boolean value as the second.
-The extension name is case\-sensitive, and matches the form shown in the output
-of \*qXorg -extension ?\*q.
-.PP
-.RS 7
-Example: the MIT-SHM extension can be disabled with the following entry:
-.PP
-.RS 4
-.nf
-.B "Section \*qExtensions\*q"
-.B " Option \*qMIT-SHM\*q \*qDisable\*q"
-.B "EndSection"
-.fi
-.RE
-.RE
-.SH "INPUTDEVICE SECTION"
-The config file may have multiple
-.B InputDevice
-sections.
-Recent X servers employ HAL or udev backends for input device enumeration
-and input hotplugging. It is usually not
-necessary to provide
-.B InputDevice
-sections in the xorg.conf if hotplugging is in use. If hotplugging is
-enabled,
-.B InputDevice
-sections using the
-.B mouse, kbd
-and
-.B vmmouse
-driver will be ignored.
-.PP
-If hotplugging is disabled, there will normally
-be at least two: one for the core (primary) keyboard
-and one for the core pointer.
-If either of these two is missing, a default configuration for the missing
-ones will be used. In the absence of an explicitly specified core input
-device, the first
-.B InputDevice
-marked as
-.B CorePointer
-(or
-.BR CoreKeyboard )
-is used.
-If there is no match there, the first
-.B InputDevice
-that uses the \(lqmouse\(rq (or \(lqkbd\(rq) driver is used.
-The final fallback is to use built\-in default configurations.
-Currently the default configuration may not work as expected on all platforms.
-.PP
-.B InputDevice
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B "Section \*qInputDevice\*q"
-.BI " Identifier \*q" name \*q
-.BI " Driver \*q" inputdriver \*q
-.I " options"
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-and
-.B Driver
-entries are required in all
-.B InputDevice
-sections.
-All other entries are optional.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this input device.
-The
-.B Driver
-entry specifies the name of the driver to use for this input device.
-When using the loadable server, the input driver module
-.RI \*q inputdriver \*q
-will be loaded for each active
-.B InputDevice
-section.
-An
-.B InputDevice
-section is considered active if it is referenced by an active
-.B ServerLayout
-section, if it is referenced by the
-.B \-keyboard
-or
-.B \-pointer
-command line options, or if it is selected implicitly as the core pointer
-or keyboard device in the absence of such explicit references.
-The most commonly used input drivers are
-.BR evdev (__drivermansuffix__)
-on Linux systems, and
-.BR kbd (__drivermansuffix__)
-and
-.BR mousedrv (__drivermansuffix__)
-on other platforms.
-.PP
-.PP
-.B InputDevice
-sections recognise some driver\-independent
-.BR Options ,
-which are described here.
-See the individual input driver manual pages for a description of the
-device\-specific options.
-.TP 7
-.BI "Option \*qAutoServerLayout\*q \*q" boolean \*q
-Always add the device to the ServerLayout section used by this instance of
-the server. This affects implied layouts as well as explicit layouts
-specified in the configuration and/or on the command line.
-.TP 7
-.BI "Option \*qCorePointer\*q"
-Deprecated, see
-.B Floating
-.TP 7
-.BI "Option \*qCoreKeyboard\*q"
-Deprecated, see
-.B Floating
-.TP 7
-.BI "Option \*qAlwaysCore\*q \*q" boolean \*q
-Deprecated, see
-.B Floating
-.TP 7
-.BI "Option \*qSendCoreEvents\*q \*q" boolean \*q
-Deprecated, see
-.B Floating
-
-.TP 7
-.BI "Option \*qFloating\*q \*q" boolean \*q
-When enabled, the input device is set up floating and does not
-report events through any master device or control a cursor. The device is
-only available to clients using the X Input Extension API. This option is
-disabled by default.
-The options
-.B CorePointer,
-.B CoreKeyboard,
-.B AlwaysCore,
-and
-.B SendCoreEvents,
-are the inverse of option
-.B Floating
-(i.e.
-.B SendCoreEvents \*qon\*q
-is equivalent to
-.B Floating \*qoff\*q
-).
-
-This option controls the startup behavior only, a device
-may be reattached or set floating at runtime.
-.PP
-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
-the most important acceleration options are discussed here.
-.TP 7
-.BI "Option \*qAccelerationProfile\*q \*q" integer \*q
-Select the profile. In layman's terms, the profile constitutes the "feeling" of
-the acceleration. More formally, it defines how the transfer function (actual
-acceleration as a function of current device velocity and acceleration controls)
-is constructed. This is mainly a matter of personal preference.
-.PP
-.RS 6
-.nf
-.B " 0 classic (mostly compatible)"
-.B "-1 none (only constant deceleration is applied)"
-.B " 1 device-dependent"
-.B " 2 polynomial (polynomial function)"
-.B " 3 smooth linear (soft knee, then linear)"
-.B " 4 simple (normal when slow, otherwise accelerated)"
-.B " 5 power (power function)"
-.B " 6 linear (more speed, more acceleration)"
-.B " 7 limited (like linear, but maxes out at threshold)"
-.fi
-.RE
-.TP 7
-.BI "Option \*qConstantDeceleration\*q \*q" real \*q
-Makes the pointer go
-.B deceleration
-times slower than normal. Most useful for high-resolution devices.
-.TP 7
-.BI "Option \*qAdaptiveDeceleration\*q \*q" real \*q
-Allows to actually decelerate the pointer when going slow. At most, it will be
-.B adaptive deceleration
-times slower. Enables precise pointer placement without sacrificing speed.
-.TP 7
-.BI "Option \*qAccelerationScheme\*q \*q" string \*q
-Selects the scheme, which is the underlying algorithm.
-.PP
-.RS 7
-.nf
-.B "predictable default algorithm (behaving more predictable)"
-.B "lightweight old acceleration code (as specified in the X protocol spec)"
-.B "none no acceleration or deceleration"
-.fi
-.RE
-.TP 7
-.BI "Option \*qAccelerationNumerator\*q \*q" integer \*q
-.TP 7
-.BI "Option \*qAccelerationDenominator\*q \*q" integer \*q
-Set numerator and denominator of the acceleration factor. The acceleration
-factor is a rational which, together with threshold, can be used to tweak
-profiles to suit the users needs. The
-.B simple
-and
-.B limited
-profiles use it directly (i.e. they accelerate by the factor), for other
-profiles it should hold that a higher acceleration factor leads to a faster
-pointer. Typically, 1 is unaccelerated and values up to 5 are sensible.
-.TP 7
-.BI "Option \*qAccelerationThreshold\*q \*q" integer \*q
-Set the threshold, which is roughly the velocity (usually device units per 10
-ms) required for acceleration to become effective. The precise effect varies
-with the profile however.
-
-.SH "INPUTCLASS SECTION"
-The config file may have multiple
-.B InputClass
-sections.
-These sections are optional and are used to provide configuration for a
-class of input devices as they are automatically added. An input device can
-match more than one
-.B InputClass
-section. Each class can override settings from a previous class, so it is
-best to arrange the sections with the most generic matches first.
-.PP
-.B InputClass
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B "Section \*qInputClass\*q"
-.BI " Identifier \*q" name \*q
-.I " entries"
-.I " ..."
-.I " options"
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-entry is required in all
-.B InputClass
-sections.
-All other entries are optional.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this input class.
-The
-.B Driver
-entry specifies the name of the driver to use for this input device.
-After all classes have been examined, the
-.RI \*q inputdriver \*q
-module from the first
-.B Driver
-entry will be enabled when using the loadable server.
-.PP
-When an input device is automatically added, its characteristics are
-checked against all
-.B InputClass
-sections. Each section can contain optional entries to narrow the match
-of the class. If none of the optional entries appear, the
-.B InputClass
-section is generic and will match any input device. If more than one of
-these entries appear, they all must match for the configuration to apply.
-.PP
-There are two types of match entries used in
-.B InputClass
-sections. The first allows various tokens to be matched against attributes
-of the device. An entry can be constructed to match attributes from different
-devices by separating arguments with a '|' character. Multiple entries of the
-same type may be supplied to add multiple matching conditions on the same
-attribute. For example:
-.PP
-.RS 4
-.nf
-.B "Section \*qInputClass\*q"
-.B " Identifier \*qMy Class\*q"
-.B " # product string must contain example and
-.B " # either gizmo or gadget
-.B " MatchProduct \*qexample\*q
-.B " MatchProduct \*qgizmo|gadget\*q
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.TP 7
-.BI "MatchProduct \*q" matchproduct \*q
-This entry can be used to check if the substring
-.RI \*q matchproduct \*q
-occurs in the device's product name.
-.TP 7
-.BI "MatchVendor \*q" matchvendor \*q
-This entry can be used to check if the substring
-.RI \*q matchvendor \*q
-occurs in the device's vendor name.
-.TP 7
-.BI "MatchDevicePath \*q" matchdevice \*q
-This entry can be used to check if the device file matches the
-.RI \*q matchdevice \*q
-pathname pattern.
-.TP 7
-.BI "MatchOS \*q" matchos \*q
-This entry can be used to check if the operating system matches the
-case-insensitive
-.RI \*q matchos \*q
-string. This entry is only supported on platforms providing the
-.BR uname (2)
-system call.
-.TP 7
-.BI "MatchPnPID \*q" matchpnp \*q
-The device's Plug and Play (PnP) ID can be checked against the
-.RI \*q matchpnp \*q
-shell wildcard pattern.
-.TP 7
-.BI "MatchUSBID \*q" matchusb \*q
-The device's USB ID can be checked against the
-.RI \*q matchusb \*q
-shell wildcard pattern. The ID is constructed as lowercase hexadecimal numbers
-separated by a ':'. This is the same format as the
-.BR lsusb (8)
-program.
-.TP 7
-.BI "MatchDriver \*q" matchdriver \*q
-Check the case-sensitive string
-.RI \*q matchdriver \*q
-against the currently configured driver of the device. Ordering of sections
-using this entry is important since it will not match unless the driver has
-been set by the config backend or a previous
-.B InputClass
-section.
-.TP 7
-.BI "MatchTag \*q" matchtag \*q
-This entry can be used to check if tags assigned by the config backend
-matches the
-.RI \*q matchtag \*q
-pattern. A match is found if at least one of the tags given in
-.RI \*q matchtag \*q
-matches at least one of the tags assigned by the backend.
-.PP
-The second type of entry is used to match device types. These entries take a
-boolean argument similar to
-.B Option
-entries.
-.TP 7
-.BI "MatchIsKeyboard \*q" bool \*q
-.TP 7
-.BI "MatchIsPointer \*q" bool \*q
-.TP 7
-.BI "MatchIsJoystick \*q" bool \*q
-.TP 7
-.BI "MatchIsTablet \*q" bool \*q
-.TP 7
-.BI "MatchIsTouchpad \*q" bool \*q
-.TP 7
-.BI "MatchIsTouchscreen \*q" bool \*q
-.PP
-When an input device has been matched to the
-.B InputClass
-section, any
-.B Option
-entries are applied to the device. One
-.B InputClass
-specific
-.B Option
-is recognized. See the
-.B InputDevice
-section above for a description of the remaining
-.B Option
-entries.
-.TP 7
-.BI "Option \*qIgnore\*q \*q" boolean \*q
-This optional entry specifies that the device should be ignored entirely,
-and not added to the server. This can be useful when the device is handled
-by another program and no X events should be generated.
-.SH "DEVICE SECTION"
-The config file may have multiple
-.B Device
-sections.
-There must be at least one, for the video card being used.
-.PP
-.B Device
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B "Section \*qDevice\*q"
-.BI " Identifier \*q" name \*q
-.BI " Driver \*q" driver \*q
-.I " entries"
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-and
-.B Driver
-entries are required in all
-.B Device
-sections. All other entries are optional.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this graphics device.
-The
-.B Driver
-entry specifies the name of the driver to use for this graphics device.
-When using the loadable server, the driver module
-.RI \*q driver \*q
-will be loaded for each active
-.B Device
-section.
-A
-.B Device
-section is considered active if it is referenced by an active
-.B Screen
-section.
-.PP
-.B Device
-sections recognise some driver\-independent entries and
-.BR Options ,
-which are described here.
-Not all drivers make use of these
-driver\-independent entries, and many of those that do don't require them
-to be specified because the information is auto\-detected.
-See the individual graphics driver manual pages for further information
-about this, and for a description of the device\-specific options.
-Note that most of the
-.B Options
-listed here (but not the other entries) may be specified in the
-.B Screen
-section instead of here in the
-.B Device
-section.
-.TP 7
-.BI "BusID \*q" bus\-id \*q
-This specifies the bus location of the graphics card.
-For PCI/AGP cards,
-the
-.I bus\-id
-string has the form
-.BI PCI: bus : device : function
-(e.g., \(lqPCI:1:0:0\(rq might be appropriate for an AGP card).
-This field is usually optional in single-head configurations when using
-the primary graphics card.
-In multi-head configurations, or when using a secondary graphics card in a
-single-head configuration, this entry is mandatory.
-Its main purpose is to make an unambiguous connection between the device
-section and the hardware it is representing.
-This information can usually be found by running the pciaccess tool
-scanpci.
-.TP 7
-.BI "Screen " number
-This option is mandatory for cards where a single PCI entity can drive more
-than one display (i.e., multiple CRTCs sharing a single graphics accelerator
-and video memory).
-One
-.B Device
-section is required for each head, and this
-parameter determines which head each of the
-.B Device
-sections applies to.
-The legal values of
-.I number
-range from 0 to one less than the total number of heads per entity.
-Most drivers require that the primary screen (0) be present.
-.TP 7
-.BI "Chipset \*q" chipset \*q
-This usually optional entry specifies the chipset used on the graphics
-board.
-In most cases this entry is not required because the drivers will probe the
-hardware to determine the chipset type.
-Don't specify it unless the driver-specific documentation recommends that you
-do.
-.TP 7
-.BI "Ramdac \*q" ramdac\-type \*q
-This optional entry specifies the type of RAMDAC used on the graphics
-board.
-This is only used by a few of the drivers, and in most cases it is not
-required because the drivers will probe the hardware to determine the
-RAMDAC type where possible.
-Don't specify it unless the driver-specific documentation recommends that you
-do.
-.TP 7
-.BI "DacSpeed " speed
-.TP 7
-.BI "DacSpeed " "speed\-8 speed\-16 speed\-24 speed\-32"
-This optional entry specifies the RAMDAC speed rating (which is usually
-printed on the RAMDAC chip).
-The speed is in MHz.
-When one value is given, it applies to all framebuffer pixel sizes.
-When multiple values are given, they apply to the framebuffer pixel sizes
-8, 16, 24 and 32 respectively.
-This is not used by many drivers, and only needs to be specified when the
-speed rating of the RAMDAC is different from the defaults built in to
-driver, or when the driver can't auto-detect the correct defaults.
-Don't specify it unless the driver-specific documentation recommends that you
-do.
-.TP 7
-.BI "Clocks " "clock ..."
-specifies the pixel that are on your graphics board.
-The clocks are in MHz, and may be specified as a floating point number.
-The value is stored internally to the nearest kHz.
-The ordering of the clocks is important.
-It must match the order in which they are selected on the graphics board.
-Multiple
-.B Clocks
-lines may be specified, and each is concatenated to form the list.
-Most drivers do not use this entry, and it is only required for some older
-boards with non-programmable clocks.
-Don't specify this entry unless the driver-specific documentation explicitly
-recommends that you do.
-.TP
-.BI "ClockChip \*q" clockchip\-type \*q
-This optional entry is used to specify the clock chip type on graphics
-boards which have a programmable clock generator.
-Only a few __xservername__ drivers support programmable clock chips.
-For details, see the appropriate driver manual page.
-.TP 7
-.BI "VideoRam " "mem"
-This optional entry specifies the amount of video ram that is installed
-on the graphics board.
-This is measured in kBytes.
-In most cases this is not required because the __xservername__ server probes
-the graphics board to determine this quantity.
-The driver-specific documentation should indicate when it might be needed.
-.TP 7
-.BI "BiosBase " "baseaddress"
-This optional entry specifies the base address of the video BIOS for
-the VGA board.
-This address is normally auto-detected, and should only be specified if the
-driver-specific documentation recommends it.
-.TP 7
-.BI "MemBase " "baseaddress"
-This optional entry specifies the memory base address of a graphics
-board's linear frame buffer.
-This entry is not used by many drivers, and it should only be specified if
-the driver-specific documentation recommends it.
-.TP 7
-.BI "IOBase " "baseaddress"
-This optional entry specifies the IO base address.
-This entry is not used by many drivers, and it should only be specified if
-the driver-specific documentation recommends it.
-.TP 7
-.BI "ChipID " "id"
-This optional entry specifies a numerical ID representing the chip type.
-For PCI cards, it is usually the device ID.
-This can be used to override the auto-detection, but that should only be done
-when the driver-specific documentation recommends it.
-.TP 7
-.BI "ChipRev " "rev"
-This optional entry specifies the chip revision number.
-This can be used to override the auto-detection, but that should only be done
-when the driver-specific documentation recommends it.
-.TP 7
-.BI "TextClockFreq " "freq"
-This optional entry specifies the pixel clock frequency that is used
-for the regular text mode.
-The frequency is specified in MHz.
-This is rarely used.
-.TP 7
-.BI "Option \*qModeDebug\*q \*q" boolean \*q
-Enable printing of additional debugging information about modesetting to
-the server log.
-.ig
-.TP 7
-This optional entry allows an IRQ number to be specified.
-..
-.TP 7
-.B Options
-Option flags may be specified in the
-.B Device
-sections.
-These include driver\-specific options and driver\-independent options.
-The former are described in the driver\-specific documentation.
-Some of the latter are described below in the section about the
-.B Screen
-section, and they may also be included here.
-
-.SH "VIDEOADAPTOR SECTION"
-Nobody wants to say how this works.
-Maybe nobody knows ...
-
-.SH "MONITOR SECTION"
-The config file may have multiple
-.B Monitor
-sections.
-There should normally be at least one, for the monitor being used,
-but a default configuration will be created when one isn't specified.
-.PP
-.B Monitor
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B "Section \*qMonitor\*q"
-.BI " Identifier \*q" name \*q
-.I " entries"
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.PP
-The only mandatory entry in a
-.B Monitor
-section is the
-.B Identifier
-entry.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this monitor.
-The
-.B Monitor
-section may be used to provide information about the specifications of the
-monitor, monitor-specific
-.BR Options ,
-and information about the video modes to use with the monitor.
-.PP
-With RandR 1.2-enabled drivers, monitor sections may be tied to specific
-outputs of the video card. Using the name of the output defined by the video
-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
-
-(for example,
-.B Option \*qMonitor-VGA\*q \*qVGA monitor\*q
-for a VGA output)
-.PP
-In the absence of specific association of monitor sections to outputs, if a
-monitor section is present the server will associate it with an output to
-preserve compatibility for previous single-head configurations.
-.PP
-Specifying video modes is optional because the server will use the DDC or other
-information provided by the monitor to automatically configure the list of
-modes available.
-When modes are specified explicitly in the
-.B Monitor
-section (with the
-.BR Modes ,
-.BR ModeLine ,
-or
-.B UseModes
-keywords), built-in modes with the same names are not included.
-Built-in modes with different names are, however, still implicitly included,
-when they meet the requirements of the monitor.
-.PP
-The entries that may be used in
-.B Monitor
-sections are described below.
-.TP 7
-.BI "VendorName \*q" vendor \*q
-This optional entry specifies the monitor's manufacturer.
-.TP 7
-.BI "ModelName \*q" model \*q
-This optional entry specifies the monitor's model.
-.TP 7
-.BI "HorizSync " "horizsync\-range"
-gives the range(s) of horizontal sync frequencies supported by the
-monitor.
-.I horizsync\-range
-may be a comma separated list of either discrete values or ranges of
-values.
-A range of values is two values separated by a dash.
-By default the values are in units of kHz.
-They may be specified in MHz or Hz
-if
-.B MHz
-or
-.B Hz
-is added to the end of the line.
-The data given here is used by the __xservername__ server to determine if video
-modes are within the specifications of the monitor.
-This information should be available in the monitor's handbook.
-If this entry is omitted, a default range of 28\-33kHz is used.
-.TP 7
-.BI "VertRefresh " "vertrefresh\-range"
-gives the range(s) of vertical refresh frequencies supported by the
-monitor.
-.I vertrefresh\-range
-may be a comma separated list of either discrete values or ranges of
-values.
-A range of values is two values separated by a dash.
-By default the values are in units of Hz.
-They may be specified in MHz or kHz
-if
-.B MHz
-or
-.B kHz
-is added to the end of the line.
-The data given here is used by the __xservername__ server to determine if video
-modes are within the specifications of the monitor.
-This information should be available in the monitor's handbook.
-If this entry is omitted, a default range of 43\-72Hz is used.
-.TP 7
-.BI "DisplaySize " "width height"
-This optional entry gives the width and height, in millimetres, of the
-picture area of the monitor.
-If given this is used to calculate the horizontal and vertical pitch (DPI) of
-the screen.
-.TP 7
-.BI "Gamma " "gamma\-value"
-.TP 7
-.BI "Gamma " "red\-gamma green\-gamma blue\-gamma"
-This is an optional entry that can be used to specify the gamma correction
-for the monitor.
-It may be specified as either a single value or as three separate RGB values.
-The values should be in the range 0.1 to 10.0, and the default is 1.0.
-Not all drivers are capable of using this information.
-.TP 7
-.BI "UseModes \*q" modesection\-id \*q
-Include the set of modes listed in the
-.B Modes
-section called
-.IR modesection\-id.
-This makes all of the modes defined in that section available for use by
-this monitor.
-.TP 7
-.BI "Mode \*q" name \*q
-This is an optional multi-line entry that can be used to provide
-definitions for video modes for the monitor.
-In most cases this isn't necessary because the built-in set of VESA standard
-modes will be sufficient.
-The
-.B Mode
-keyword indicates the start of a multi-line video mode description.
-The mode description is terminated with the
-.B EndMode
-keyword.
-The mode description consists of the following entries:
-.RS 7
-.TP 4
-.BI "DotClock " clock
-is the dot (pixel) clock rate to be used for the mode.
-.TP 4
-.BI "HTimings " "hdisp hsyncstart hsyncend htotal"
-specifies the horizontal timings for the mode.
-.TP 4
-.BI "VTimings " "vdisp vsyncstart vsyncend vtotal"
-specifies the vertical timings for the mode.
-.TP 4
-.BI "Flags \*q" flag \*q " ..."
-specifies an optional set of mode flags, each of which is a separate
-string in double quotes.
-.B \*qInterlace\*q
-indicates that the mode is interlaced.
-.B \*qDoubleScan\*q
-indicates a mode where each scanline is doubled.
-.B \*q+HSync\*q
-and
-.B \*q\-HSync\*q
-can be used to select the polarity of the HSync signal.
-.B \*q+VSync\*q
-and
-.B \*q\-VSync\*q
-can be used to select the polarity of the VSync signal.
-.B \*qComposite\*q
-can be used to specify composite sync on hardware where this is supported.
-Additionally, on some hardware,
-.B \*q+CSync\*q
-and
-.B \*q\-CSync\*q
-may be used to select the composite sync polarity.
-.TP 4
-.BI "HSkew " hskew
-specifies the number of pixels (towards the right edge of the screen) by
-which the display enable signal is to be skewed.
-Not all drivers use this information.
-This option might become necessary to override the default value supplied
-by the server (if any).
-\(lqRoving\(rq horizontal lines indicate this value needs to be increased.
-If the last few pixels on a scan line appear on the left of the screen,
-this value should be decreased.
-.TP 4
-.BI "VScan " vscan
-specifies the number of times each scanline is painted on the screen.
-Not all drivers use this information.
-Values less than 1 are treated as 1, which is the default.
-Generally, the
-.B \*qDoubleScan\*q
-.B Flag
-mentioned above doubles this value.
-.RE
-.TP 7
-.BI "ModeLine \*q" name \*q " mode\-description"
-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.
-In most cases this isn't necessary because the built\-in set of VESA
-standard modes will be sufficient.
-.PP
-.RS 7
-The
-.I mode\-description
-is in four sections, the first three of which are mandatory.
-The first is the dot (pixel) clock.
-This is a single number specifying the pixel clock rate for the mode in
-MHz.
-The second section is a list of four numbers specifying the horizontal
-timings.
-These numbers are the
-.IR hdisp ,
-.IR hsyncstart ,
-.IR hsyncend ,
-and
-.I htotal
-values.
-The third section is a list of four numbers specifying the vertical
-timings.
-These numbers are the
-.IR vdisp ,
-.IR vsyncstart ,
-.IR vsyncend ,
-and
-.I vtotal
-values.
-The final section is a list of flags specifying other characteristics of
-the mode.
-.B Interlace
-indicates that the mode is interlaced.
-.B DoubleScan
-indicates a mode where each scanline is doubled.
-.B +HSync
-and
-.B \-HSync
-can be used to select the polarity of the HSync signal.
-.B +VSync
-and
-.B \-VSync
-can be used to select the polarity of the VSync signal.
-.B Composite
-can be used to specify composite sync on hardware where this is supported.
-Additionally, on some hardware,
-.B +CSync
-and
-.B \-CSync
-may be used to select the composite sync polarity.
-The
-.B HSkew
-and
-.B VScan
-options mentioned above in the
-.B Modes
-entry description can also be used here.
-.RE
-.TP 7
-.BI "Option " "\*qDPMS\*q " \*qbool\*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
-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
-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
-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"
-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
-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
-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
-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
-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
-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
-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
-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
-This optional entry specifies the minimum dot clock, in kHz, that is supported
-by the monitor.
-.TP 7
-.BI "Option " "\*qMaxClock\*q " \*qfrequency\*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
-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
-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.
-(RandR 1.2-supporting drivers only)
-
-.SH "MODES SECTION"
-The config file may have multiple
-.B Modes
-sections, or none.
-These sections provide a way of defining sets of video modes independently
-of the
-.B Monitor
-sections.
-.B Monitor
-sections may include the definitions provided in these sections by
-using the
-.B UseModes
-keyword.
-In most cases the
-.B Modes
-sections are not necessary because the built\-in set of VESA standard modes
-will be sufficient.
-.PP
-.B Modes
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B "Section \*qModes\*q"
-.BI " Identifier \*q" name \*q
-.I " entries"
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-entry specifies the unique name for this set of mode descriptions.
-The other entries permitted in
-.B Modes
-sections are the
-.B Mode
-and
-.B ModeLine
-entries that are described above in the
-.B Monitor
-section.
-.SH "SCREEN SECTION"
-The config file may have multiple
-.B Screen
-sections.
-There must be at least one, for the \(lqscreen\(rq being used.
-A \(lqscreen\(rq represents the binding of a graphics device
-.RB ( Device
-section) and a monitor
-.RB ( Monitor
-section).
-A
-.B Screen
-section is considered \(lqactive\(rq if it is referenced by an active
-.B ServerLayout
-section or by the
-.B \-screen
-command line option.
-If neither of those is present, the first
-.B Screen
-section found in the config file is considered the active one.
-.PP
-.B Screen
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B "Section \*qScreen\*q"
-.BI " Identifier \*q" name \*q
-.BI " Device \*q" devid \*q
-.BI " Monitor \*q" monid \*q
-.I " entries"
-.I " ..."
-.BI " SubSection \*qDisplay\*q"
-.I " entries"
-.I " ...
-.B " EndSubSection"
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-and
-.B Device
-entries are mandatory.
-All others are optional.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this screen.
-The
-.B Screen
-section provides information specific to the whole screen, including
-screen\-specific
-.BR Options .
-In multi\-head configurations, there will be multiple active
-.B Screen
-sections, one for each head.
-The entries available
-for this section are:
-.TP 7
-.BI "Device \*q" device\-id \*q
-This mandatory entry specifies the
-.B Device
-section to be used for this screen.
-This is what ties a specific graphics card to a screen.
-The
-.I device\-id
-must match the
-.B Identifier
-of a
-.B Device
-section in the config file.
-.TP 7
-.BI "Monitor \*q" monitor\-id \*q
-specifies which monitor description is to be used for this screen.
-If a
-.B Monitor
-name is not specified, a default configuration is used.
-Currently the default configuration may not function as expected on all
-platforms.
-.TP 7
-.BI "VideoAdaptor \*q" xv\-id \*q
-specifies an optional Xv video adaptor description to be used with this
-screen.
-.TP 7
-.BI "DefaultDepth " depth
-specifies which color depth the server should use by default.
-The
-.B \-depth
-command line option can be used to override this.
-If neither is specified, the default depth is driver\-specific, but in most
-cases is 8.
-.TP 7
-.BI "DefaultFbBpp " bpp
-specifies which framebuffer layout to use by default.
-The
-.B \-fbbpp
-command line option can be used to override this.
-In most cases the driver will chose the best default value for this.
-The only case where there is even a choice in this value is for depth 24,
-where some hardware supports both a packed 24 bit framebuffer layout and a
-sparse 32 bit framebuffer layout.
-.TP 7
-.B Options
-Various
-.B Option
-flags may be specified in the
-.B Screen
-section.
-Some are driver\-specific and are described in the driver documentation.
-Others are driver\-independent, and will eventually be described here.
-.\" XXX These should really be in an xaa man page.
-.TP 7
-.BI "Option \*qAccel\*q"
-Enables XAA (X Acceleration Architecture), a mechanism that makes video cards'
-2D hardware acceleration available to the __xservername__ server.
-This option is on by default, but it may be necessary to turn it off if
-there are bugs in the driver.
-There are many options to disable specific accelerated operations, listed
-below.
-Note that disabling an operation will have no effect if the operation is
-not accelerated (whether due to lack of support in the hardware or in the
-driver).
-.TP 7
-.BI "Option \*qInitPrimary\*q \*q" boolean \*q
-Use the Int10 module to initialize the primary graphics card.
-Normally, only secondary cards are soft-booted using the Int10 module, as the
-primary card has already been initialized by the BIOS at boot time.
-Default: false.
-.TP 7
-.BI "Option \*qNoInt10\*q \*q" boolean \*q
-Disables the Int10 module, a module that uses the int10 call to the BIOS
-of the graphics card to initialize it.
-Default: false.
-.TP 7
-.BI "Option \*qNoMTRR\*q"
-Disables MTRR (Memory Type Range Register) support, a feature of modern
-processors which can improve video performance by a factor of up to 2.5.
-Some hardware has buggy MTRR support, and some video drivers have been
-known to exhibit problems when MTRR's are used.
-.TP 7
-.BI "Option \*qXaaNoCPUToScreenColorExpandFill\*q"
-Disables accelerated rectangular expansion blits from source patterns
-stored in system memory (using a memory\-mapped aperture).
-.TP 7
-.BI "Option \*qXaaNoColor8x8PatternFillRect\*q"
-Disables accelerated fills of a rectangular region with a full\-color
-pattern.
-.TP 7
-.BI "Option \*qXaaNoColor8x8PatternFillTrap\*q"
-Disables accelerated fills of a trapezoidal region with a full\-color
-pattern.
-.TP 7
-.BI "Option \*qXaaNoDashedBresenhamLine\*q"
-Disables accelerated dashed Bresenham line draws.
-.TP 7
-.BI "Option \*qXaaNoDashedTwoPointLine\*q"
-Disables accelerated dashed line draws between two arbitrary points.
-.TP 7
-.BI "Option \*qXaaNoImageWriteRect\*q"
-Disables accelerated transfers of full\-color rectangular patterns from
-system memory to video memory (using a memory\-mapped aperture).
-.TP 7
-.BI "Option \*qXaaNoMono8x8PatternFillRect\*q"
-Disables accelerated fills of a rectangular region with a monochrome
-pattern.
-.TP 7
-.BI "Option \*qXaaNoMono8x8PatternFillTrap\*q"
-Disables accelerated fills of a trapezoidal region with a monochrome
-pattern.
-.TP 7
-.BI "Option \*qXaaNoOffscreenPixmaps\*q"
-Disables accelerated draws into pixmaps stored in offscreen video memory.
-.TP 7
-.BI "Option \*qXaaNoPixmapCache\*q"
-Disables caching of patterns in offscreen video memory.
-.TP 7
-.BI "Option \*qXaaNoScanlineCPUToScreenColorExpandFill\*q"
-Disables accelerated rectangular expansion blits from source patterns
-stored in system memory (one scan line at a time).
-.TP 7
-.BI "Option \*qXaaNoScanlineImageWriteRect\*q"
-Disables accelerated transfers of full\-color rectangular patterns from
-system memory to video memory (one scan line at a time).
-.TP 7
-.BI "Option \*qXaaNoScreenToScreenColorExpandFill\*q"
-Disables accelerated rectangular expansion blits from source patterns
-stored in offscreen video memory.
-.TP 7
-.BI "Option \*qXaaNoScreenToScreenCopy\*q"
-Disables accelerated copies of rectangular regions from one part of
-video memory to another part of video memory.
-.TP 7
-.BI "Option \*qXaaNoSolidBresenhamLine\*q"
-Disables accelerated solid Bresenham line draws.
-.TP 7
-.BI "Option \*qXaaNoSolidFillRect\*q"
-Disables accelerated solid\-color fills of rectangles.
-.TP 7
-.BI "Option \*qXaaNoSolidFillTrap\*q"
-Disables accelerated solid\-color fills of Bresenham trapezoids.
-.TP 7
-.BI "Option \*qXaaNoSolidHorVertLine\*q"
-Disables accelerated solid horizontal and vertical line draws.
-.TP 7
-.BI "Option \*qXaaNoSolidTwoPointLine\*q"
-Disables accelerated solid line draws between two arbitrary points.
-.PP
-Each
-.B Screen
-section may optionally contain one or more
-.B Display
-subsections.
-Those subsections provide depth/fbbpp specific configuration information,
-and the one chosen depends on the depth and/or fbbpp that is being used for
-the screen.
-The
-.B Display
-subsection format is described in the section below.
-
-.SH "DISPLAY SUBSECTION"
-Each
-.B Screen
-section may have multiple
-.B Display
-subsections.
-The \(lqactive\(rq
-.B Display
-subsection is the first that matches the depth and/or fbbpp values being
-used, or failing that, the first that has neither a depth or fbbpp value
-specified.
-The
-.B Display
-subsections are optional.
-When there isn't one that matches the depth and/or fbbpp values being used,
-all the parameters that can be specified here fall back to their defaults.
-.PP
-.B Display
-subsections have the following format:
-.PP
-.RS 4
-.nf
-.B " SubSection \*qDisplay\*q"
-.BI " Depth " depth
-.I " entries"
-.I " ..."
-.B " EndSubSection"
-.fi
-.RE
-.TP 7
-.BI "Depth " depth
-This entry specifies what colour depth the
-.B Display
-subsection is to be used for.
-This entry is usually specified, but it may be omitted to create a match\-all
-.B Display
-subsection or when wishing to match only against the
-.B FbBpp
-parameter.
-The range of
-.I depth
-values that are allowed depends on the driver.
-Most drivers support 8, 15, 16 and 24.
-Some also support 1 and/or 4, and some may support other values (like 30).
-Note:
-.I depth
-means the number of bits in a pixel that are actually used to determine
-the pixel colour.
-32 is not a valid
-.I depth
-value.
-Most hardware that uses 32 bits per pixel only uses 24 of them to hold the
-colour information, which means that the colour depth is 24, not 32.
-.TP 7
-.BI "FbBpp " bpp
-This entry specifies the framebuffer format this
-.B Display
-subsection is to be used for.
-This entry is only needed when providing depth 24 configurations that allow
-a choice between a 24 bpp packed framebuffer format and a 32bpp sparse
-framebuffer format.
-In most cases this entry should not be used.
-.TP 7
-.BI "Weight " "red\-weight green\-weight blue\-weight"
-This optional entry specifies the relative RGB weighting to be used
-for a screen is being used at depth 16 for drivers that allow multiple
-formats.
-This may also be specified from the command line with the
-.B \-weight
-option (see
-.BR __xservername__(__appmansuffix__)).
-.TP 7
-.BI "Virtual " "xdim ydim"
-This optional entry specifies the virtual screen resolution to be used.
-.I xdim
-must be a multiple of either 8 or 16 for most drivers, and a multiple
-of 32 when running in monochrome mode.
-The given value will be rounded down if this is not the case.
-Video modes which are too large for the specified virtual size will be
-rejected.
-If this entry is not present, the virtual screen resolution will be set to
-accommodate all the valid video modes given in the
-.B Modes
-entry.
-Some drivers/hardware combinations do not support virtual screens.
-Refer to the appropriate driver\-specific documentation for details.
-.TP 7
-.BI "ViewPort " "x0 y0"
-This optional entry sets the upper left corner of the initial display.
-This is only relevant when the virtual screen resolution is different
-from the resolution of the initial video mode.
-If this entry is not given, then the initial display will be centered in
-the virtual display area.
-.TP 7
-.BI "Modes \*q" mode\-name \*q " ..."
-This optional entry specifies the list of video modes to use.
-Each
-.I mode\-name
-specified must be in double quotes.
-They must correspond to those specified or referenced in the appropriate
-.B Monitor
-section (including implicitly referenced built\-in VESA standard modes).
-The server will delete modes from this list which don't satisfy various
-requirements.
-The first valid mode in this list will be the default display mode for
-startup.
-The list of valid modes is converted internally into a circular list.
-It is possible to switch to the next mode with
-.B Ctrl+Alt+Keypad\-Plus
-and to the previous mode with
-.BR Ctrl+Alt+Keypad\-Minus .
-When this entry is omitted, the valid modes referenced by the appropriate
-.B Monitor
-section will be used. If the
-.B Monitor
-section contains no modes, then the selection will be taken from the
-built-in VESA standard modes.
-.TP 7
-.BI "Visual \*q" visual\-name \*q
-This optional entry sets the default root visual type.
-This may also be specified from the command line (see the
-.BR Xserver(__appmansuffix__)
-man page).
-The visual types available for depth 8 are (default is
-.BR PseudoColor ):
-.PP
-.RS 11
-.nf
-.B StaticGray
-.B GrayScale
-.B StaticColor
-.B PseudoColor
-.B TrueColor
-.B DirectColor
-.fi
-.RE
-.PP
-.RS 7
-The visual type available for the depths 15, 16 and 24 are (default is
-.BR TrueColor ):
-.PP
-.RS 4
-.nf
-.B TrueColor
-.B DirectColor
-.fi
-.RE
-.PP
-Not all drivers support
-.B DirectColor
-at these depths.
-.PP
-The visual types available for the depth 4 are (default is
-.BR StaticColor ):
-.PP
-.RS 4
-.nf
-.B StaticGray
-.B GrayScale
-.B StaticColor
-.B PseudoColor
-.fi
-.RE
-.PP
-The visual type available for the depth 1 (monochrome) is
-.BR StaticGray .
-.RE
-.TP 7
-.BI "Black " "red green blue"
-This optional entry allows the \(lqblack\(rq colour to be specified.
-This is only supported at depth 1.
-The default is black.
-.TP 7
-.BI "White " "red green blue"
-This optional entry allows the \(lqwhite\(rq colour to be specified.
-This is only supported at depth 1.
-The default is white.
-.TP 7
-.B Options
-Option flags may be specified in the
-.B Display
-subsections.
-These may include driver\-specific options and driver\-independent options.
-The former are described in the driver\-specific documentation.
-Some of the latter are described above in the section about the
-.B Screen
-section, and they may also be included here.
-.SH "SERVERLAYOUT SECTION"
-The config file may have multiple
-.B ServerLayout
-sections.
-A \(lqserver layout\(rq represents the binding of one or more screens
-.RB ( Screen
-sections) and one or more input devices
-.RB ( InputDevice
-sections) to form a complete configuration.
-In multi\-head configurations, it also specifies the relative layout of the
-heads.
-A
-.B ServerLayout
-section is considered \(lqactive\(rq if it is referenced by the
-.B \-layout
-command line option or by an
-.B "Option \*qDefaultServerLayout\*q"
-entry in the
-.B ServerFlags
-section (the former takes precedence over the latter).
-If those options are not used, the first
-.B ServerLayout
-section found in the config file is considered the active one.
-If no
-.B ServerLayout
-sections are present, the single active screen and two active (core)
-input devices are selected as described in the relevant sections above.
-.PP
-.B ServerLayout
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B "Section \*qServerLayout\*q"
-.BI " Identifier \*q" name \*q
-.BI " Screen \*q" screen\-id \*q
-.I " ..."
-.BI " InputDevice \*q" idev\-id \*q
-.I " ..."
-.I " options"
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.PP
-Each
-.B ServerLayout
-section must have an
-.B Identifier
-entry and at least one
-.B Screen
-entry.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this server layout.
-The
-.B ServerLayout
-section provides information specific to the whole session, including
-session\-specific
-.BR Options .
-The
-.B ServerFlags
-options (described above) may be specified here, and ones given here
-override those given in the
-.B ServerFlags
-section.
-.PP
-The entries that may be used in this section are described here.
-.TP 7
-.BI "Screen " "screen\-num" " \*qscreen\-id\*q " "position\-information"
-One of these entries must be given for each screen being used in
-a session.
-The
-.I screen\-id
-field is mandatory, and specifies the
-.B Screen
-section being referenced.
-The
-.I screen\-num
-field is optional, and may be used to specify the screen number
-in multi\-head configurations.
-When this field is omitted, the screens will be numbered in the order that
-they are listed in.
-The numbering starts from 0, and must be consecutive.
-The
-.I position\-information
-field describes the way multiple screens are positioned.
-There are a number of different ways that this information can be provided:
-.RS 7
-.TP 4
-.I "x y"
-.TP 4
-.BI "Absolute " "x y"
-These both specify that the upper left corner's coordinates are
-.RI ( x , y ).
-The
-.B Absolute
-keyword is optional.
-Some older versions of XFree86 (4.2 and earlier) don't recognise the
-.B Absolute
-keyword, so it's safest to just specify the coordinates without it.
-.TP 4
-.BI "RightOf \*q" screen\-id \*q
-.TP 4
-.BI "LeftOf \*q" screen\-id \*q
-.TP 4
-.BI "Above \*q" screen\-id \*q
-.TP 4
-.BI "Below \*q" screen\-id \*q
-.TP 4
-.BI "Relative \*q" screen\-id \*q " x y"
-These give the screen's location relative to another screen.
-The first four position the screen immediately to the right, left, above or
-below the other screen.
-When positioning to the right or left, the top edges are aligned.
-When positioning above or below, the left edges are aligned.
-The
-.B Relative
-form specifies the offset of the screen's origin (upper left corner)
-relative to the origin of another screen.
-.RE
-.TP 7
-.BI "InputDevice \*q" idev\-id "\*q \*q" option \*q " ..."
-One of these entries should be given for each input device being used in
-a session.
-Normally at least two are required, one each for the core pointer and
-keyboard devices.
-If either of those is missing, suitable
-.B InputDevice
-entries are searched for using the method described above in the
-.B INPUTDEVICE
-section. The
-.I idev\-id
-field is mandatory, and specifies the name of the
-.B InputDevice
-section being referenced.
-Multiple
-.I option
-fields may be specified, each in double quotes.
-The options permitted here are any that may also be given in the
-.B InputDevice
-sections.
-Normally only session\-specific input device options would be used here.
-The most commonly used options are:
-.PP
-.RS 11
-.nf
-.B \*qCorePointer\*q
-.B \*qCoreKeyboard\*q
-.B \*qSendCoreEvents\*q
-.fi
-.RE
-.PP
-.RS 7
-and the first two should normally be used to indicate the core pointer
-and core keyboard devices respectively.
-.RE
-.TP 7
-.B Options
-In addition to the following, any option permitted in the
-.B ServerFlags
-section may also be specified here.
-When the same option appears in both places, the value given here overrides
-the one given in the
-.B ServerFlags
-section.
-.TP 7
-.BI "Option \*qIsolateDevice\*q \*q" bus\-id \*q
-Restrict device resets to the specified
-.IR bus\-id .
-See the
-.B BusID
-option (described in
-.BR "DEVICE SECTION" ,
-above) for the format of the
-.I bus\-id
-parameter.
-This option overrides
-.BR SingleCard ,
-if specified.
-At present, only PCI devices can be isolated in this manner.
-.TP 7
-.BI "Option \*qSingleCard\*q \*q" boolean \*q
-As
-.BR IsolateDevice ,
-except that the bus ID of the first device in the layout is used.
-.PP
-Here is an example of a
-.B ServerLayout
-section for a dual headed configuration with two mice:
-.PP
-.RS 4
-.nf
-.B "Section \*qServerLayout\*q"
-.B " Identifier \*qLayout 1\*q"
-.B " Screen \*qMGA 1\*q"
-.B " Screen \*qMGA 2\*q RightOf \*qMGA 1\*q"
-.B " InputDevice \*qKeyboard 1\*q \*qCoreKeyboard\*q"
-.B " InputDevice \*qMouse 1\*q \*qCorePointer\*q"
-.B " InputDevice \*qMouse 2\*q \*qSendCoreEvents\*q"
-.B " Option \*qBlankTime\*q \*q5\*q"
-.B "EndSection"
-.fi
-.RE
-.SH "DRI SECTION"
-This optional section is used to provide some information for the
-Direct Rendering Infrastructure.
-Details about the format of this section can be found on-line at
-.IR <http://dri.freedesktop.org/> .
-.SH "VENDOR SECTION"
-The optional
-.B Vendor
-section may be used to provide vendor\-specific configuration information.
-Multiple
-.B Vendor
-sections may be present, and they may contain an
-.B Identifier
-entry and multiple
-.B Option
-flags.
-The data therein is not used in this release.
-.PP
-.SH "SEE ALSO"
-General:
-.BR X (__miscmansuffix__),
-.BR Xserver (__appmansuffix__),
-.BR __xservername__ (__appmansuffix__),
-.BR cvt (__appmansuffix__),
-.BR gtf (__appmansuffix__).
-.PP
-.B "Not all modules or interfaces are available on all platforms."
-.PP
-Display drivers:
-.BR apm (__drivermansuffix__),
-.BR ati (__drivermansuffix__),
-.BR chips (__drivermansuffix__),
-.BR cirrus (__drivermansuffix__),
-.BR cyrix (__drivermansuffix__),
-.BR fbdev (__drivermansuffix__),
-.BR glide (__drivermansuffix__),
-.BR glint (__drivermansuffix__),
-.BR i128 (__drivermansuffix__),
-.BR i740 (__drivermansuffix__),
-.BR imstt (__drivermansuffix__),
-.BR intel (__drivermansuffix__),
-.BR mga (__drivermansuffix__),
-.BR neomagic (__drivermansuffix__),
-.BR nv (__drivermansuffix__),
-.BR openchrome (__drivermansuffix__),
-.BR r128 (__drivermansuffix__),
-.BR radeon (__drivermansuffix__),
-.BR rendition (__drivermansuffix__),
-.BR savage (__drivermansuffix__),
-.BR s3virge (__drivermansuffix__),
-.BR siliconmotion (__drivermansuffix__),
-.BR sis (__drivermansuffix__),
-.BR sisusb (__drivermansuffix__),
-.BR sunbw2 (__drivermansuffix__),
-.BR suncg14 (__drivermansuffix__),
-.BR suncg3 (__drivermansuffix__),
-.BR suncg6 (__drivermansuffix__),
-.BR sunffb (__drivermansuffix__),
-.BR sunleo (__drivermansuffix__),
-.BR suntcx (__drivermansuffix__),
-.BR tdfx (__drivermansuffix__),
-.\" .BR tga (__drivermansuffix__),
-.BR trident (__drivermansuffix__),
-.BR tseng (__drivermansuffix__),
-.BR vesa (__drivermansuffix__),
-.BR vmware (__drivermansuffix__),
-.BR voodoo (__drivermansuffix__),
-.BR wsfb (__drivermansuffix__),
-.BR xgi (__drivermansuffix__),
-.BR xgixp (__drivermansuffix__).
-.PP
-Input drivers:
-.BR acecad (__drivermansuffix__),
-.BR citron (__drivermansuffix__),
-.BR elographics (__drivermansuffix__),
-.BR evdev (__drivermansuffix__),
-.BR fpit (__drivermansuffix__),
-.BR joystick (__drivermansuffix__),
-.BR kbd (__drivermansuffix__),
-.BR mousedrv (__drivermansuffix__),
-.BR mutouch (__drivermansuffix__),
-.BR penmount (__drivermansuffix__),
-.BR synaptics (__drivermansuffix__),
-.BR vmmouse (__drivermansuffix__),
-.BR void (__drivermansuffix__),
-.BR wacom (__drivermansuffix__).
-.PP
-Other modules and interfaces:
-.BR exa (__drivermansuffix__),
-.BR fbdevhw (__drivermansuffix__),
-.\" .BR shadowfb (__drivermansuffix__),
-.BR v4l (__drivermansuffix__).
-.br
-.SH AUTHORS
-This manual page was largely rewritten by David Dawes
-.IR <dawes@xfree86.org> .
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH __xconfigfile__ __filemansuffix__ __vendorversion__
+.SH NAME
+__xconfigfile__ and __xconfigdir__ \- configuration files for
+__xservername__ X server
+.SH INTRODUCTION
+.B __xservername__
+supports several mechanisms for supplying/obtaining configuration and
+run-time parameters: command line options, environment variables, the
+__xconfigfile__ and __xconfigdir__ configuration files, auto-detection,
+and fallback defaults. When the same information is supplied in more
+than one way, the highest precedence mechanism is used. The list of
+mechanisms is ordered from highest precedence to lowest. Note that not
+all parameters can be supplied via all methods. The available command
+line options and environment variables (and some defaults) are
+described in the Xserver(__appmansuffix__) and
+__xservername__(__appmansuffix__) manual pages. Most configuration file
+parameters, with their defaults, are described below. Driver and module
+specific configuration parameters are described in the relevant driver
+or module manual page.
+.SH DESCRIPTION
+.B __xservername__
+uses a configuration file called
+.I __xconfigfile__
+and files ending in the suffix
+.I .conf
+from the directory
+.I __xconfigdir__
+for its initial setup.
+The
+.I __xconfigfile__
+configuration file is searched for in the following places when the
+server is started as a normal user:
+.PP
+.RS 4
+.nf
+.IR /etc/X11/ <cmdline>
+.IR __projectroot__/etc/X11/ <cmdline>
+.IB /etc/X11/ $XORGCONFIG
+.IB __projectroot__/etc/X11/ $XORGCONFIG
+.I /etc/X11/__xconfigfile__
+.I /etc/__xconfigfile__
+.IR __projectroot__/etc/X11/__xconfigfile__. <hostname>
+.I __projectroot__/etc/X11/__xconfigfile__
+.IR __projectroot__/lib/X11/__xconfigfile__. <hostname>
+.I __projectroot__/lib/X11/__xconfigfile__
+.fi
+.RE
+.PP
+where
+.I <cmdline>
+is a relative path (with no \(lq..\(rq components) specified with the
+.B \-config
+command line option,
+.B $XORGCONFIG
+is the relative path (with no \(lq..\(rq components) specified by that
+environment variable, and
+.I <hostname>
+is the machine's hostname as reported by
+.BR gethostname (__libmansuffix__).
+.PP
+When the __xservername__ server is started by the \(lqroot\(rq user, the config file
+search locations are as follows:
+.PP
+.RS 4
+.nf
+<cmdline>
+.IR /etc/X11/ <cmdline>
+.IR __projectroot__/etc/X11/ <cmdline>
+.B $XORGCONFIG
+.IB /etc/X11/ $XORGCONFIG
+.IB __projectroot__/etc/X11/ $XORGCONFIG
+.I /etc/X11/__xconfigfile__
+.I /etc/__xconfigfile__
+.IR __projectroot__/etc/X11/__xconfigfile__. <hostname>
+.I __projectroot__/etc/X11/__xconfigfile__
+.IR __projectroot__/lib/X11/__xconfigfile__. <hostname>
+.I __projectroot__/lib/X11/__xconfigfile__
+.fi
+.RE
+.PP
+where
+.I <cmdline>
+is the path specified with the
+.B \-config
+command line option (which may be absolute or relative),
+.B $XORGCONFIG
+is the path specified by that
+environment variable (absolute or relative),
+.B $HOME
+is the path specified by that environment variable (usually the home
+directory), and
+.I <hostname>
+is the machine's hostname as reported by
+.BR gethostname (__libmansuffix__).
+.PP
+Additional configuration files are searched for in the following
+directories when the server is started as a normal user:
+.PP
+.RS 4
+.nf
+.IR /etc/X11/ <cmdline>
+.IR __sysconfdir__/X11/ <cmdline>
+.I /etc/X11/__xconfigdir__
+.I __sysconfdir__/X11/__xconfigdir__
+.fi
+.RE
+.PP
+where
+.I <cmdline>
+is a relative path (with no \(lq..\(rq components) specified with the
+.B \-configdir
+command line option.
+.PP
+When the __xservername__ server is started by the \(lqroot\(rq user, the
+config directory search locations are as follows:
+.PP
+.RS 4
+.nf
+<cmdline>
+.IR /etc/X11/ <cmdline>
+.IR __sysconfdir__/X11/ <cmdline>
+.I /etc/X11/__xconfigdir__
+.I __sysconfdir__/X11/__xconfigdir__
+.fi
+.RE
+.PP
+where
+.I <cmdline>
+is the path specified with the
+.B \-configdir
+command line option (which may be absolute or relative).
+.PP
+Finally, configuration files will also be searched for in directories
+reserved for system use. These are to separate configuration files from
+the vendor or 3rd party packages from those of local administration.
+These files are found in the following directories:
+.PP
+.RS 4
+.nf
+.I /usr/share/X11/__xconfigdir__
+.I __datadir__/X11/__xconfigdir__
+.fi
+.RE
+.PP
+The
+.I __xconfigfile__
+and
+.I __xconfigdir__
+files are composed of a number of sections which may be present in any order,
+or omitted to use default configuration values.
+Each section has the form:
+.PP
+.RS 4
+.nf
+.BI "Section \*q" SectionName \*q
+.RI " " SectionEntry
+ ...
+.B EndSection
+.fi
+.RE
+.PP
+The section names are:
+.PP
+.RS 4
+.nf
+.BR "Files " "File pathnames"
+.BR "ServerFlags " "Server flags"
+.BR "Module " "Dynamic module loading"
+.BR "Extensions " "Extension enabling"
+.BR "InputDevice " "Input device description"
+.BR "InputClass " "Input class description"
+.BR "Device " "Graphics device description"
+.BR "VideoAdaptor " "Xv video adaptor description"
+.BR "Monitor " "Monitor description"
+.BR "Modes " "Video modes descriptions"
+.BR "Screen " "Screen configuration"
+.BR "ServerLayout " "Overall layout"
+.BR "DRI " "DRI\-specific configuration"
+.BR "Vendor " "Vendor\-specific configuration"
+.fi
+.RE
+.PP
+The following obsolete section names are still recognised for compatibility
+purposes.
+In new config files, the
+.B InputDevice
+section should be used instead.
+.PP
+.RS 4
+.nf
+.BR "Keyboard " "Keyboard configuration"
+.BR "Pointer " "Pointer/mouse configuration"
+.fi
+.RE
+.PP
+The old
+.B XInput
+section is no longer recognised.
+.PP
+The
+.B ServerLayout
+sections are at the highest level.
+They bind together the input and output devices that will be used in a session.
+The input devices are described in the
+.B InputDevice
+sections.
+Output devices usually consist of multiple independent components (e.g.,
+a graphics board and a monitor).
+These multiple components are bound together in the
+.B Screen
+sections, and it is these that are referenced by the
+.B ServerLayout
+section.
+Each
+.B Screen
+section binds together a graphics board and a monitor.
+The graphics boards are described in the
+.B Device
+sections, and the monitors are described in the
+.B Monitor
+sections.
+.PP
+Config file keywords are case\-insensitive, and \(lq_\(rq characters are
+ignored.
+Most strings (including
+.B Option
+names) are also case-insensitive, and insensitive to white space and
+\(lq_\(rq characters.
+.PP
+Each config file entry usually takes up a single line in the file. They
+consist of a keyword, which is possibly followed by one or more arguments,
+with the number and types of the arguments depending on the keyword.
+The argument types are:
+.PP
+.RS 4
+.nf
+.BR "Integer " "an integer number in decimal, hex or octal"
+.BR "Real " "a floating point number"
+.BR "String " "a string enclosed in double quote marks (\*q)"
+.fi
+.RE
+.PP
+Note: hex integer values must be prefixed with \(lq0x\(rq, and octal values
+with \(lq0\(rq.
+.PP
+A special keyword called
+.B Option
+may be used to provide free\-form data to various components of the server.
+The
+.B Option
+keyword takes either one or two string arguments.
+The first is the option name, and the optional second argument is the
+option value.
+Some commonly used option value types include:
+.PP
+.RS 4
+.nf
+.BR "Integer " "an integer number in decimal, hex or octal"
+.BR "Real " "a floating point number"
+.BR "String " "a sequence of characters"
+.BR "Boolean " "a boolean value (see below)"
+.BR "Frequency " "a frequency value (see below)"
+.fi
+.RE
+.PP
+Note that
+.I all
+.B Option
+values, not just strings, must be enclosed in quotes.
+.PP
+Boolean options may optionally have a value specified.
+When no value is specified, the option's value is
+.BR TRUE .
+The following boolean option values are recognised as
+.BR TRUE :
+.PP
+.RS 4
+.BR 1 ,
+.BR on ,
+.BR true ,
+.B yes
+.RE
+.PP
+and the following boolean option values are recognised as
+.BR FALSE :
+.PP
+.RS 4
+.BR 0 ,
+.BR off ,
+.BR false ,
+.B no
+.RE
+.PP
+If an option name is prefixed with
+.RB \*q No \*q,
+then the option value is negated.
+.PP
+Example: the following option entries are equivalent:
+.PP
+.RS 4
+.nf
+.B "Option \*qAccel\*q \*qOff\*q"
+.B "Option \*qNoAccel\*q"
+.B "Option \*qNoAccel\*q \*qOn\*q"
+.B "Option \*qAccel\*q \*qfalse\*q"
+.B "Option \*qAccel\*q \*qno\*q"
+.fi
+.RE
+.PP
+Frequency option values consist of a real number that is optionally
+followed by one of the following frequency units:
+.PP
+.RS 4
+.BR Hz ,
+.BR k ,
+.BR kHz ,
+.BR M ,
+.B MHz
+.RE
+.PP
+When the unit name is omitted, the correct units will be determined from
+the value and the expectations of the appropriate range of the value.
+It is recommended that the units always be specified when using frequency
+option values to avoid any errors in determining the value.
+.SH "FILES SECTION"
+The
+.B Files
+section is used to specify some path names required by the server.
+Some of these paths can also be set from the command line (see
+.BR Xserver (__appmansuffix__)
+and
+.BR __xservername__ (__appmansuffix__)).
+The command line settings override the values specified in the config
+file.
+The
+.B Files
+section is optional, as are all of the entries that may appear in it.
+.PP
+The entries that can appear in this section are:
+.TP 7
+.BI "FontPath \*q" path \*q
+sets the search path for fonts.
+This path is a comma separated list of font path elements which the __xservername__
+server searches for font databases.
+Multiple
+.B FontPath
+entries may be specified, and they will be concatenated to build up the
+fontpath used by the server. Font path elements can be absolute
+directory paths, catalogue directories or a font server identifier. The
+formats of the later two are explained below:
+.PP
+.RS 7
+Catalogue directories:
+.PP
+.RS 4
+Catalogue directories can be specified using the prefix \fBcatalogue:\fR
+before the directory name. The directory can then be populated with
+symlinks pointing to the real font directories, using the following
+syntax in the symlink name:
+.PP
+.RS 4
+.IR <identifier> : [attribute]: pri= <priority>
+.RE
+.PP
+where
+.I <identifier>
+is an alphanumeric identifier,
+.I [attribute]
+is an attribute which will be passed to the underlying FPE and
+.I <priority>
+is a number used to order the fontfile FPEs. Examples:
+.PP
+.RS 4
+.nf
+.I 75dpi:unscaled:pri=20 -> /usr/share/X11/fonts/75dpi
+.I gscript:pri=60 -> /usr/share/fonts/default/ghostscript
+.I misc:unscaled:pri=10 \-> /usr/share/X11/fonts/misc
+.fi
+.PP
+.RE .RE .RE
+.PP
+.RS 7
+Font server identifiers:
+.PP
+.RS 4
+Font server identifiers have the form:
+.RS 4
+.PP
+.IR <trans> / <hostname> : <port\-number>
+.RE
+.PP
+where
+.I <trans>
+is the transport type to use to connect to the font server (e.g.,
+.B unix
+for UNIX\-domain sockets or
+.B tcp
+for a TCP/IP connection),
+.I <hostname>
+is the hostname of the machine running the font server, and
+.I <port\-number>
+is the port number that the font server is listening on (usually 7100).
+.RE
+.PP
+When this entry is not specified in the config file, the server falls back
+to the compiled\-in default font path, which contains the following
+font path elements (which can be set inside a catalogue directory):
+.PP
+.RS 4
+.nf
+.I __datadir__/fonts/X11/misc/
+.I __datadir__/fonts/X11/TTF/
+.I __datadir__/fonts/X11/OTF/
+.I __datadir__/fonts/X11/Type1/
+.I __datadir__/fonts/X11/100dpi/
+.I __datadir__/fonts/X11/75dpi/
+.fi
+.RE
+.PP
+Font path elements that are found to be invalid are removed from the
+font path when the server starts up.
+.RE
+.TP 7
+.BI "ModulePath \*q" path \*q
+sets the search path for loadable __xservername__ server modules.
+This path is a comma separated list of directories which the __xservername__ server
+searches for loadable modules loading in the order specified.
+Multiple
+.B ModulePath
+entries may be specified, and they will be concatenated to build the
+module search path used by the server. The default module path is
+.PP
+.RS 11
+__modulepath__
+.RE
+.\" The LogFile keyword is not currently implemented
+.ig
+.TP 7
+.BI "LogFile \*q" path \*q
+sets the name of the __xservername__ server log file.
+The default log file name is
+.PP
+.RS 11
+.RI __logdir__/__xservername__. <n> .log
+.RE
+.PP
+.RS 7
+where
+.I <n>
+is the display number for the __xservername__ server.
+..
+.TP 7
+.BI "XkbDir \*q" path \*q
+sets the base directory for keyboard layout files. The
+.B \-xkbdir
+command line option can be used to override this. The default directory is
+.PP
+.RS 11
+__xkbdir__
+.RE
+.SH "SERVERFLAGS SECTION"
+In addition to options specific to this section (described below), the
+.B ServerFlags
+section is used to specify some global
+__xservername__ server options.
+All of the entries in this section are
+.BR Options ,
+although for compatibility purposes some of the old style entries are
+still recognised.
+Those old style entries are not documented here, and using them is
+discouraged.
+The
+.B ServerFlags
+section is optional, as are the entries that may be specified in it.
+.PP
+.B Options
+specified in this section (with the exception of the
+.B \*qDefaultServerLayout\*q
+.BR Option )
+may be overridden by
+.B Options
+specified in the active
+.B ServerLayout
+section.
+Options with command line equivalents are overridden when their command
+line equivalent is used.
+The options recognised by this section are:
+.TP 7
+.BI "Option \*qDefaultServerLayout\*q \*q" layout\-id \*q
+This specifies the default
+.B ServerLayout
+section to use in the absence of the
+.B \-layout
+command line option.
+.TP 7
+.BI "Option \*qNoTrapSignals\*q \*q" boolean \*q
+This prevents the __xservername__ server from trapping a range of unexpected fatal
+signals and exiting cleanly.
+Instead, the __xservername__ server will die and drop core where the fault occurred.
+The default behaviour is for the __xservername__ server to exit cleanly, but still drop a
+core file.
+In general you never want to use this option unless you are debugging an __xservername__
+server problem and know how to deal with the consequences.
+.TP 7
+.BI "Option \*qUseSIGIO\*q \*q" boolean \*q
+This controls whether the __xservername__ server requests that events from
+input devices be reported via a SIGIO signal handler (also known as SIGPOLL
+on some platforms), or only reported via the standard select(3) loop.
+The default behaviour is platform specific. In general you do not want to
+use this option unless you are debugging the __xservername__ server, or
+working around a specific bug until it is fixed, and understand the
+consequences.
+.TP 7
+.BI "Option \*qDontVTSwitch\*q \*q" boolean \*q
+This disallows the use of the
+.BI Ctrl+Alt+F n
+sequence (where
+.RI F n
+refers to one of the numbered function keys).
+That sequence is normally used to switch to another \*qvirtual terminal\*q
+on operating systems that have this feature.
+When this option is enabled, that key sequence has no special meaning and
+is passed to clients.
+Default: off.
+.TP 7
+.BI "Option \*qDontZap\*q \*q" boolean \*q
+This disallows the use of the
+.B Terminate_Server
+XKB action (usually on Ctrl+Alt+Backspace, depending on XKB options).
+This action is normally used to terminate the __xservername__ server.
+When this option is enabled, the action has no effect.
+Default: off.
+.TP 7
+.BI "Option \*qDontZoom\*q \*q" boolean \*q
+This disallows the use of the
+.B Ctrl+Alt+Keypad\-Plus
+and
+.B Ctrl+Alt+Keypad\-Minus
+sequences.
+These sequences allows you to switch between video modes.
+When this option is enabled, those key sequences have no special meaning
+and are passed to clients.
+Default: off.
+.TP 7
+.BI "Option \*qDisableVidModeExtension\*q \*q" boolean \*q
+This disables the parts of the VidMode extension used by the xvidtune client
+that can be used to change the video modes.
+Default: the VidMode extension is enabled.
+.TP 7
+.BI "Option \*qAllowNonLocalXvidtune\*q \*q" boolean \*q
+This allows the xvidtune client (and other clients that use the VidMode
+extension) to connect from another host.
+Default: off.
+.TP 7
+.BI "Option \*qAllowMouseOpenFail\*q \*q" boolean \*q
+This tells the mousedrv(__drivermansuffix__) and vmmouse(__drivermansuffix__)
+drivers to not report failure if the mouse device can't be opened/initialised.
+It has no effect on the evdev(__drivermansuffix__) or other drivers.
+Default: false.
+.TP 7
+.BI "Option \*qVTSysReq\*q \*q" boolean \*q
+enables the SYSV\-style VT switch sequence for non\-SYSV systems
+which support VT switching.
+This sequence is
+.B Alt\-SysRq
+followed by a function key
+.RB ( Fn ).
+This prevents the __xservername__ server trapping the
+keys used for the default VT switch sequence, which means that clients can
+access them.
+Default: off.
+.TP 7
+.BI "Option \*qBlankTime\*q \*q" time \*q
+sets the inactivity timeout for the
+.B blank
+phase of the screensaver.
+.I time
+is in minutes.
+This is equivalent to the __xservername__ server's
+.B \-s
+flag, and the value can be changed at run\-time with
+.BR xset(__appmansuffix__).
+Default: 10 minutes.
+.TP 7
+.BI "Option \*qStandbyTime\*q \*q" time \*q
+sets the inactivity timeout for the
+.B standby
+phase of DPMS mode.
+.I time
+is in minutes, and the value can be changed at run\-time with
+.BR xset(__appmansuffix__).
+Default: 10 minutes.
+This is only suitable for VESA DPMS compatible monitors, and may not be
+supported by all video drivers.
+It is only enabled for screens that have the
+.B \*qDPMS\*q
+option set (see the MONITOR section below).
+.TP 7
+.BI "Option \*qSuspendTime\*q \*q" time \*q
+sets the inactivity timeout for the
+.B suspend
+phase of DPMS mode.
+.I time
+is in minutes, and the value can be changed at run\-time with
+.BR xset(__appmansuffix__).
+Default: 10 minutes.
+This is only suitable for VESA DPMS compatible monitors, and may not be
+supported by all video drivers.
+It is only enabled for screens that have the
+.B \*qDPMS\*q
+option set (see the MONITOR section below).
+.TP 7
+.BI "Option \*qOffTime\*q \*q" time \*q
+sets the inactivity timeout for the
+.B off
+phase of DPMS mode.
+.I time
+is in minutes, and the value can be changed at run\-time with
+.BR xset(__appmansuffix__).
+Default: 10 minutes.
+This is only suitable for VESA DPMS compatible monitors, and may not be
+supported by all video drivers.
+It is only enabled for screens that have the
+.B \*qDPMS\*q
+option set (see the MONITOR section below).
+.TP 7
+.BI "Option \*qPixmap\*q \*q" bpp \*q
+This sets the pixmap format to use for depth 24.
+Allowed values for
+.I bpp
+are 24 and 32.
+Default: 32 unless driver constraints don't allow this (which is rare).
+Note: some clients don't behave well when this value is set to 24.
+.TP 7
+.BI "Option \*qPC98\*q \*q" boolean \*q
+Specify that the machine is a Japanese PC\-98 machine.
+This should not be enabled for anything other than the Japanese\-specific
+PC\-98 architecture.
+Default: auto\-detected.
+.TP 7
+.BI "Option \*qNoPM\*q \*q" boolean \*q
+Disables something to do with power management events.
+Default: PM enabled on platforms that support it.
+.TP 7
+.BI "Option \*qXinerama\*q \*q" boolean \*q
+enable or disable XINERAMA extension.
+Default is disabled.
+.TP 7
+.BI "Option \*qAIGLX\*q \*q" boolean \*q
+enable or disable AIGLX. AIGLX is enabled by default.
+.TP 7
+.BI "Option \*qDRI2\*q \*q" boolean \*q
+enable or disable DRI2. DRI2 is disabled by default.
+.TP 7
+.BI "Option \*qGlxVisuals\*q \*q" string \*q
+This option controls how many GLX visuals the GLX modules sets up.
+The default value is
+.BR "typical" ,
+which will setup up a typical subset of
+the GLXFBConfigs provided by the driver as GLX visuals. Other options are
+.BR "minimal" ,
+which will set up the minimal set allowed by the GLX specification and
+.BR "all"
+which will setup GLX visuals for all GLXFBConfigs.
+.TP 7
+.BI "Option \*qUseDefaultFontPath\*q \*q" boolean \*q
+Include the default font path even if other paths are specified in
+xorg.conf. If enabled, other font paths are included as well. Enabled by
+default.
+.TP 7
+.BI "Option \*qIgnoreABI\*q \*q" boolean \*q
+Allow modules built for a different, potentially incompatible version of
+the X server to load. Disabled by default.
+.TP 7
+.BI "Option \*qAutoAddDevices\*q \*q" boolean \*q
+If this option is disabled, then no devices will be added from HAL events.
+Enabled by default.
+.TP 7
+.BI "Option \*qAutoEnableDevices\*q \*q" boolean \*q
+If this option is disabled, then the devices will be added (and the
+DevicePresenceNotify event sent), but not enabled, thus leaving policy up
+to the client.
+Enabled by default.
+.TP 7
+.BI "Option \*qLog\*q \*q" string \*q
+This option controls whether the log is flushed and/or synced to disk after
+each message.
+Possible values are
+.B flush
+or
+.BR sync .
+Unset by default.
+.SH "MODULE SECTION"
+The
+.B Module
+section is used to specify which __xservername__ server modules should be loaded.
+This section is ignored when the __xservername__ server is built in static form.
+The type of modules normally loaded in this section are __xservername__ server
+extension modules.
+Most other module types are loaded automatically when they are needed via
+other mechanisms.
+The
+.B Module
+section is optional, as are all of the entries that may be specified in
+it.
+.PP
+Entries in this section may be in two forms.
+The first and most commonly used form is an entry that uses the
+.B Load
+keyword, as described here:
+.TP 7
+.BI "Load \*q" modulename \*q
+This instructs the server to load the module called
+.IR modulename .
+The module name given should be the module's standard name, not the
+module file name.
+The standard name is case\-sensitive, and does not include the \(lqlib\(rq
+prefix, or the \(lq.a\(rq, \(lq.o\(rq, or \(lq.so\(rq suffixes.
+.PP
+.RS 7
+Example: the DRI extension module can be loaded with the following entry:
+.PP
+.RS 4
+.B "Load \*qdri\*q"
+.RE
+.RE
+.TP 7
+.BI "Disable \*q" modulename \*q
+This instructs the server to not load the module called
+.IR modulename .
+Some modules are loaded by default in the server, and this overrides that
+default. If a
+.B Load
+instruction is given for the same module, it overrides the
+.B Disable
+instruction and the module is loaded. The module name given should be the
+module's standard name, not the module file name. As with the
+.B Load
+instruction, the standard name is case-sensitive, and does not include the
+"lib" prefix, or the ".a", ".o", or ".so" suffixes.
+.PP
+The second form of entry is a
+.BR SubSection,
+with the subsection name being the module name, and the contents of the
+.B SubSection
+being
+.B Options
+that are passed to the module when it is loaded.
+.PP
+Example: the extmod module (which contains a miscellaneous group of
+server extensions) can be loaded, with the XFree86\-DGA extension
+disabled by using the following entry:
+.PP
+.RS 4
+.nf
+.B "SubSection \*qextmod\*q"
+.B " Option \*qomit XFree86\-DGA\*q"
+.B EndSubSection
+.fi
+.RE
+.PP
+Modules are searched for in each directory specified in the
+.B ModulePath
+search path, and in the drivers, extensions, input, internal, and
+multimedia subdirectories of each of those directories.
+In addition to this, operating system specific subdirectories of all
+the above are searched first if they exist.
+.PP
+To see what extension modules are available, check the extensions
+subdirectory under:
+.PP
+.RS 4
+.nf
+__modulepath__
+.fi
+.RE
+.PP
+The \(lqextmod\(rq, \(lqdbe\(rq, \(lqdri\(rq, \(lqdri2\(rq, \(lqglx\(rq,
+and \(lqrecord\(rq extension modules are loaded automatically, if they
+are present, unless disabled with \*qDisable\*q entries.
+It is recommended
+that at very least the \(lqextmod\(rq extension module be loaded.
+If it isn't, some commonly used server extensions (like the SHAPE
+extension) will not be available.
+.SH "EXTENSIONS SECTION"
+The
+.B Extensions
+section is used to specify which X11 protocol extensions should be enabled
+or disabled.
+The
+.B Extensions
+section is optional, as are all of the entries that may be specified in
+it.
+.PP
+Entries in this section are listed as Option statements with the name of
+the extension as the first argument, and a boolean value as the second.
+The extension name is case\-sensitive, and matches the form shown in the output
+of \*qXorg -extension ?\*q.
+.PP
+.RS 7
+Example: the MIT-SHM extension can be disabled with the following entry:
+.PP
+.RS 4
+.nf
+.B "Section \*qExtensions\*q"
+.B " Option \*qMIT-SHM\*q \*qDisable\*q"
+.B "EndSection"
+.fi
+.RE
+.RE
+.SH "INPUTDEVICE SECTION"
+The config file may have multiple
+.B InputDevice
+sections.
+Recent X servers employ HAL or udev backends for input device enumeration
+and input hotplugging. It is usually not
+necessary to provide
+.B InputDevice
+sections in the xorg.conf if hotplugging is in use. If hotplugging is
+enabled,
+.B InputDevice
+sections using the
+.B mouse, kbd
+and
+.B vmmouse
+driver will be ignored.
+.PP
+If hotplugging is disabled, there will normally
+be at least two: one for the core (primary) keyboard
+and one for the core pointer.
+If either of these two is missing, a default configuration for the missing
+ones will be used. In the absence of an explicitly specified core input
+device, the first
+.B InputDevice
+marked as
+.B CorePointer
+(or
+.BR CoreKeyboard )
+is used.
+If there is no match there, the first
+.B InputDevice
+that uses the \(lqmouse\(rq (or \(lqkbd\(rq) driver is used.
+The final fallback is to use built\-in default configurations.
+Currently the default configuration may not work as expected on all platforms.
+.PP
+.B InputDevice
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B "Section \*qInputDevice\*q"
+.BI " Identifier \*q" name \*q
+.BI " Driver \*q" inputdriver \*q
+.I " options"
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+and
+.B Driver
+entries are required in all
+.B InputDevice
+sections.
+All other entries are optional.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this input device.
+The
+.B Driver
+entry specifies the name of the driver to use for this input device.
+When using the loadable server, the input driver module
+.RI \*q inputdriver \*q
+will be loaded for each active
+.B InputDevice
+section.
+An
+.B InputDevice
+section is considered active if it is referenced by an active
+.B ServerLayout
+section, if it is referenced by the
+.B \-keyboard
+or
+.B \-pointer
+command line options, or if it is selected implicitly as the core pointer
+or keyboard device in the absence of such explicit references.
+The most commonly used input drivers are
+.BR evdev (__drivermansuffix__)
+on Linux systems, and
+.BR kbd (__drivermansuffix__)
+and
+.BR mousedrv (__drivermansuffix__)
+on other platforms.
+.PP
+.PP
+.B InputDevice
+sections recognise some driver\-independent
+.BR Options ,
+which are described here.
+See the individual input driver manual pages for a description of the
+device\-specific options.
+.TP 7
+.BI "Option \*qAutoServerLayout\*q \*q" boolean \*q
+Always add the device to the ServerLayout section used by this instance of
+the server. This affects implied layouts as well as explicit layouts
+specified in the configuration and/or on the command line.
+.TP 7
+.BI "Option \*qCorePointer\*q"
+Deprecated, see
+.B Floating
+.TP 7
+.BI "Option \*qCoreKeyboard\*q"
+Deprecated, see
+.B Floating
+.TP 7
+.BI "Option \*qAlwaysCore\*q \*q" boolean \*q
+Deprecated, see
+.B Floating
+.TP 7
+.BI "Option \*qSendCoreEvents\*q \*q" boolean \*q
+Deprecated, see
+.B Floating
+
+.TP 7
+.BI "Option \*qFloating\*q \*q" boolean \*q
+When enabled, the input device is set up floating and does not
+report events through any master device or control a cursor. The device is
+only available to clients using the X Input Extension API. This option is
+disabled by default.
+The options
+.B CorePointer,
+.B CoreKeyboard,
+.B AlwaysCore,
+and
+.B SendCoreEvents,
+are the inverse of option
+.B Floating
+(i.e.
+.B SendCoreEvents \*qon\*q
+is equivalent to
+.B Floating \*qoff\*q
+).
+
+This option controls the startup behavior only, a device
+may be reattached or set floating at runtime.
+.PP
+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
+the most important acceleration options are discussed here.
+.TP 7
+.BI "Option \*qAccelerationProfile\*q \*q" integer \*q
+Select the profile. In layman's terms, the profile constitutes the "feeling" of
+the acceleration. More formally, it defines how the transfer function (actual
+acceleration as a function of current device velocity and acceleration controls)
+is constructed. This is mainly a matter of personal preference.
+.PP
+.RS 6
+.nf
+.B " 0 classic (mostly compatible)"
+.B "-1 none (only constant deceleration is applied)"
+.B " 1 device-dependent"
+.B " 2 polynomial (polynomial function)"
+.B " 3 smooth linear (soft knee, then linear)"
+.B " 4 simple (normal when slow, otherwise accelerated)"
+.B " 5 power (power function)"
+.B " 6 linear (more speed, more acceleration)"
+.B " 7 limited (like linear, but maxes out at threshold)"
+.fi
+.RE
+.TP 7
+.BI "Option \*qConstantDeceleration\*q \*q" real \*q
+Makes the pointer go
+.B deceleration
+times slower than normal. Most useful for high-resolution devices.
+.TP 7
+.BI "Option \*qAdaptiveDeceleration\*q \*q" real \*q
+Allows to actually decelerate the pointer when going slow. At most, it will be
+.B adaptive deceleration
+times slower. Enables precise pointer placement without sacrificing speed.
+.TP 7
+.BI "Option \*qAccelerationScheme\*q \*q" string \*q
+Selects the scheme, which is the underlying algorithm.
+.PP
+.RS 7
+.nf
+.B "predictable default algorithm (behaving more predictable)"
+.B "lightweight old acceleration code (as specified in the X protocol spec)"
+.B "none no acceleration or deceleration"
+.fi
+.RE
+.TP 7
+.BI "Option \*qAccelerationNumerator\*q \*q" integer \*q
+.TP 7
+.BI "Option \*qAccelerationDenominator\*q \*q" integer \*q
+Set numerator and denominator of the acceleration factor. The acceleration
+factor is a rational which, together with threshold, can be used to tweak
+profiles to suit the users needs. The
+.B simple
+and
+.B limited
+profiles use it directly (i.e. they accelerate by the factor), for other
+profiles it should hold that a higher acceleration factor leads to a faster
+pointer. Typically, 1 is unaccelerated and values up to 5 are sensible.
+.TP 7
+.BI "Option \*qAccelerationThreshold\*q \*q" integer \*q
+Set the threshold, which is roughly the velocity (usually device units per 10
+ms) required for acceleration to become effective. The precise effect varies
+with the profile however.
+
+.SH "INPUTCLASS SECTION"
+The config file may have multiple
+.B InputClass
+sections.
+These sections are optional and are used to provide configuration for a
+class of input devices as they are automatically added. An input device can
+match more than one
+.B InputClass
+section. Each class can override settings from a previous class, so it is
+best to arrange the sections with the most generic matches first.
+.PP
+.B InputClass
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B "Section \*qInputClass\*q"
+.BI " Identifier \*q" name \*q
+.I " entries"
+.I " ..."
+.I " options"
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+entry is required in all
+.B InputClass
+sections.
+All other entries are optional.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this input class.
+The
+.B Driver
+entry specifies the name of the driver to use for this input device.
+After all classes have been examined, the
+.RI \*q inputdriver \*q
+module from the first
+.B Driver
+entry will be enabled when using the loadable server.
+.PP
+When an input device is automatically added, its characteristics are
+checked against all
+.B InputClass
+sections. Each section can contain optional entries to narrow the match
+of the class. If none of the optional entries appear, the
+.B InputClass
+section is generic and will match any input device. If more than one of
+these entries appear, they all must match for the configuration to apply.
+.PP
+There are two types of match entries used in
+.B InputClass
+sections. The first allows various tokens to be matched against attributes
+of the device. An entry can be constructed to match attributes from different
+devices by separating arguments with a '|' character. Multiple entries of the
+same type may be supplied to add multiple matching conditions on the same
+attribute. For example:
+.PP
+.RS 4
+.nf
+.B "Section \*qInputClass\*q"
+.B " Identifier \*qMy Class\*q"
+.B " # product string must contain example and
+.B " # either gizmo or gadget
+.B " MatchProduct \*qexample\*q
+.B " MatchProduct \*qgizmo|gadget\*q
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.TP 7
+.BI "MatchProduct \*q" matchproduct \*q
+This entry can be used to check if the substring
+.RI \*q matchproduct \*q
+occurs in the device's product name.
+.TP 7
+.BI "MatchVendor \*q" matchvendor \*q
+This entry can be used to check if the substring
+.RI \*q matchvendor \*q
+occurs in the device's vendor name.
+.TP 7
+.BI "MatchDevicePath \*q" matchdevice \*q
+This entry can be used to check if the device file matches the
+.RI \*q matchdevice \*q
+pathname pattern.
+.TP 7
+.BI "MatchOS \*q" matchos \*q
+This entry can be used to check if the operating system matches the
+case-insensitive
+.RI \*q matchos \*q
+string. This entry is only supported on platforms providing the
+.BR uname (2)
+system call.
+.TP 7
+.BI "MatchPnPID \*q" matchpnp \*q
+The device's Plug and Play (PnP) ID can be checked against the
+.RI \*q matchpnp \*q
+shell wildcard pattern.
+.TP 7
+.BI "MatchUSBID \*q" matchusb \*q
+The device's USB ID can be checked against the
+.RI \*q matchusb \*q
+shell wildcard pattern. The ID is constructed as lowercase hexadecimal numbers
+separated by a ':'. This is the same format as the
+.BR lsusb (8)
+program.
+.TP 7
+.BI "MatchDriver \*q" matchdriver \*q
+Check the case-sensitive string
+.RI \*q matchdriver \*q
+against the currently configured driver of the device. Ordering of sections
+using this entry is important since it will not match unless the driver has
+been set by the config backend or a previous
+.B InputClass
+section.
+.TP 7
+.BI "MatchTag \*q" matchtag \*q
+This entry can be used to check if tags assigned by the config backend
+matches the
+.RI \*q matchtag \*q
+pattern. A match is found if at least one of the tags given in
+.RI \*q matchtag \*q
+matches at least one of the tags assigned by the backend.
+.PP
+The second type of entry is used to match device types. These entries take a
+boolean argument similar to
+.B Option
+entries.
+.TP 7
+.BI "MatchIsKeyboard \*q" bool \*q
+.TP 7
+.BI "MatchIsPointer \*q" bool \*q
+.TP 7
+.BI "MatchIsJoystick \*q" bool \*q
+.TP 7
+.BI "MatchIsTablet \*q" bool \*q
+.TP 7
+.BI "MatchIsTouchpad \*q" bool \*q
+.TP 7
+.BI "MatchIsTouchscreen \*q" bool \*q
+.PP
+When an input device has been matched to the
+.B InputClass
+section, any
+.B Option
+entries are applied to the device. One
+.B InputClass
+specific
+.B Option
+is recognized. See the
+.B InputDevice
+section above for a description of the remaining
+.B Option
+entries.
+.TP 7
+.BI "Option \*qIgnore\*q \*q" boolean \*q
+This optional entry specifies that the device should be ignored entirely,
+and not added to the server. This can be useful when the device is handled
+by another program and no X events should be generated.
+.SH "DEVICE SECTION"
+The config file may have multiple
+.B Device
+sections.
+There must be at least one, for the video card being used.
+.PP
+.B Device
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B "Section \*qDevice\*q"
+.BI " Identifier \*q" name \*q
+.BI " Driver \*q" driver \*q
+.I " entries"
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+and
+.B Driver
+entries are required in all
+.B Device
+sections. All other entries are optional.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this graphics device.
+The
+.B Driver
+entry specifies the name of the driver to use for this graphics device.
+When using the loadable server, the driver module
+.RI \*q driver \*q
+will be loaded for each active
+.B Device
+section.
+A
+.B Device
+section is considered active if it is referenced by an active
+.B Screen
+section.
+.PP
+.B Device
+sections recognise some driver\-independent entries and
+.BR Options ,
+which are described here.
+Not all drivers make use of these
+driver\-independent entries, and many of those that do don't require them
+to be specified because the information is auto\-detected.
+See the individual graphics driver manual pages for further information
+about this, and for a description of the device\-specific options.
+Note that most of the
+.B Options
+listed here (but not the other entries) may be specified in the
+.B Screen
+section instead of here in the
+.B Device
+section.
+.TP 7
+.BI "BusID \*q" bus\-id \*q
+This specifies the bus location of the graphics card.
+For PCI/AGP cards,
+the
+.I bus\-id
+string has the form
+.BI PCI: bus : device : function
+(e.g., \(lqPCI:1:0:0\(rq might be appropriate for an AGP card).
+This field is usually optional in single-head configurations when using
+the primary graphics card.
+In multi-head configurations, or when using a secondary graphics card in a
+single-head configuration, this entry is mandatory.
+Its main purpose is to make an unambiguous connection between the device
+section and the hardware it is representing.
+This information can usually be found by running the pciaccess tool
+scanpci.
+.TP 7
+.BI "Screen " number
+This option is mandatory for cards where a single PCI entity can drive more
+than one display (i.e., multiple CRTCs sharing a single graphics accelerator
+and video memory).
+One
+.B Device
+section is required for each head, and this
+parameter determines which head each of the
+.B Device
+sections applies to.
+The legal values of
+.I number
+range from 0 to one less than the total number of heads per entity.
+Most drivers require that the primary screen (0) be present.
+.TP 7
+.BI "Chipset \*q" chipset \*q
+This usually optional entry specifies the chipset used on the graphics
+board.
+In most cases this entry is not required because the drivers will probe the
+hardware to determine the chipset type.
+Don't specify it unless the driver-specific documentation recommends that you
+do.
+.TP 7
+.BI "Ramdac \*q" ramdac\-type \*q
+This optional entry specifies the type of RAMDAC used on the graphics
+board.
+This is only used by a few of the drivers, and in most cases it is not
+required because the drivers will probe the hardware to determine the
+RAMDAC type where possible.
+Don't specify it unless the driver-specific documentation recommends that you
+do.
+.TP 7
+.BI "DacSpeed " speed
+.TP 7
+.BI "DacSpeed " "speed\-8 speed\-16 speed\-24 speed\-32"
+This optional entry specifies the RAMDAC speed rating (which is usually
+printed on the RAMDAC chip).
+The speed is in MHz.
+When one value is given, it applies to all framebuffer pixel sizes.
+When multiple values are given, they apply to the framebuffer pixel sizes
+8, 16, 24 and 32 respectively.
+This is not used by many drivers, and only needs to be specified when the
+speed rating of the RAMDAC is different from the defaults built in to
+driver, or when the driver can't auto-detect the correct defaults.
+Don't specify it unless the driver-specific documentation recommends that you
+do.
+.TP 7
+.BI "Clocks " "clock ..."
+specifies the pixel that are on your graphics board.
+The clocks are in MHz, and may be specified as a floating point number.
+The value is stored internally to the nearest kHz.
+The ordering of the clocks is important.
+It must match the order in which they are selected on the graphics board.
+Multiple
+.B Clocks
+lines may be specified, and each is concatenated to form the list.
+Most drivers do not use this entry, and it is only required for some older
+boards with non-programmable clocks.
+Don't specify this entry unless the driver-specific documentation explicitly
+recommends that you do.
+.TP
+.BI "ClockChip \*q" clockchip\-type \*q
+This optional entry is used to specify the clock chip type on graphics
+boards which have a programmable clock generator.
+Only a few __xservername__ drivers support programmable clock chips.
+For details, see the appropriate driver manual page.
+.TP 7
+.BI "VideoRam " "mem"
+This optional entry specifies the amount of video ram that is installed
+on the graphics board.
+This is measured in kBytes.
+In most cases this is not required because the __xservername__ server probes
+the graphics board to determine this quantity.
+The driver-specific documentation should indicate when it might be needed.
+.TP 7
+.BI "BiosBase " "baseaddress"
+This optional entry specifies the base address of the video BIOS for
+the VGA board.
+This address is normally auto-detected, and should only be specified if the
+driver-specific documentation recommends it.
+.TP 7
+.BI "MemBase " "baseaddress"
+This optional entry specifies the memory base address of a graphics
+board's linear frame buffer.
+This entry is not used by many drivers, and it should only be specified if
+the driver-specific documentation recommends it.
+.TP 7
+.BI "IOBase " "baseaddress"
+This optional entry specifies the IO base address.
+This entry is not used by many drivers, and it should only be specified if
+the driver-specific documentation recommends it.
+.TP 7
+.BI "ChipID " "id"
+This optional entry specifies a numerical ID representing the chip type.
+For PCI cards, it is usually the device ID.
+This can be used to override the auto-detection, but that should only be done
+when the driver-specific documentation recommends it.
+.TP 7
+.BI "ChipRev " "rev"
+This optional entry specifies the chip revision number.
+This can be used to override the auto-detection, but that should only be done
+when the driver-specific documentation recommends it.
+.TP 7
+.BI "TextClockFreq " "freq"
+This optional entry specifies the pixel clock frequency that is used
+for the regular text mode.
+The frequency is specified in MHz.
+This is rarely used.
+.TP 7
+.BI "Option \*qModeDebug\*q \*q" boolean \*q
+Enable printing of additional debugging information about modesetting to
+the server log.
+.ig
+.TP 7
+This optional entry allows an IRQ number to be specified.
+..
+.TP 7
+.B Options
+Option flags may be specified in the
+.B Device
+sections.
+These include driver\-specific options and driver\-independent options.
+The former are described in the driver\-specific documentation.
+Some of the latter are described below in the section about the
+.B Screen
+section, and they may also be included here.
+
+.SH "VIDEOADAPTOR SECTION"
+Nobody wants to say how this works.
+Maybe nobody knows ...
+
+.SH "MONITOR SECTION"
+The config file may have multiple
+.B Monitor
+sections.
+There should normally be at least one, for the monitor being used,
+but a default configuration will be created when one isn't specified.
+.PP
+.B Monitor
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B "Section \*qMonitor\*q"
+.BI " Identifier \*q" name \*q
+.I " entries"
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.PP
+The only mandatory entry in a
+.B Monitor
+section is the
+.B Identifier
+entry.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this monitor.
+The
+.B Monitor
+section may be used to provide information about the specifications of the
+monitor, monitor-specific
+.BR Options ,
+and information about the video modes to use with the monitor.
+.PP
+With RandR 1.2-enabled drivers, monitor sections may be tied to specific
+outputs of the video card. Using the name of the output defined by the video
+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
+
+(for example,
+.B Option \*qMonitor-VGA\*q \*qVGA monitor\*q
+for a VGA output)
+.PP
+In the absence of specific association of monitor sections to outputs, if a
+monitor section is present the server will associate it with an output to
+preserve compatibility for previous single-head configurations.
+.PP
+Specifying video modes is optional because the server will use the DDC or other
+information provided by the monitor to automatically configure the list of
+modes available.
+When modes are specified explicitly in the
+.B Monitor
+section (with the
+.BR Modes ,
+.BR ModeLine ,
+or
+.B UseModes
+keywords), built-in modes with the same names are not included.
+Built-in modes with different names are, however, still implicitly included,
+when they meet the requirements of the monitor.
+.PP
+The entries that may be used in
+.B Monitor
+sections are described below.
+.TP 7
+.BI "VendorName \*q" vendor \*q
+This optional entry specifies the monitor's manufacturer.
+.TP 7
+.BI "ModelName \*q" model \*q
+This optional entry specifies the monitor's model.
+.TP 7
+.BI "HorizSync " "horizsync\-range"
+gives the range(s) of horizontal sync frequencies supported by the
+monitor.
+.I horizsync\-range
+may be a comma separated list of either discrete values or ranges of
+values.
+A range of values is two values separated by a dash.
+By default the values are in units of kHz.
+They may be specified in MHz or Hz
+if
+.B MHz
+or
+.B Hz
+is added to the end of the line.
+The data given here is used by the __xservername__ server to determine if video
+modes are within the specifications of the monitor.
+This information should be available in the monitor's handbook.
+If this entry is omitted, a default range of 28\-33kHz is used.
+.TP 7
+.BI "VertRefresh " "vertrefresh\-range"
+gives the range(s) of vertical refresh frequencies supported by the
+monitor.
+.I vertrefresh\-range
+may be a comma separated list of either discrete values or ranges of
+values.
+A range of values is two values separated by a dash.
+By default the values are in units of Hz.
+They may be specified in MHz or kHz
+if
+.B MHz
+or
+.B kHz
+is added to the end of the line.
+The data given here is used by the __xservername__ server to determine if video
+modes are within the specifications of the monitor.
+This information should be available in the monitor's handbook.
+If this entry is omitted, a default range of 43\-72Hz is used.
+.TP 7
+.BI "DisplaySize " "width height"
+This optional entry gives the width and height, in millimetres, of the
+picture area of the monitor.
+If given this is used to calculate the horizontal and vertical pitch (DPI) of
+the screen.
+.TP 7
+.BI "Gamma " "gamma\-value"
+.TP 7
+.BI "Gamma " "red\-gamma green\-gamma blue\-gamma"
+This is an optional entry that can be used to specify the gamma correction
+for the monitor.
+It may be specified as either a single value or as three separate RGB values.
+The values should be in the range 0.1 to 10.0, and the default is 1.0.
+Not all drivers are capable of using this information.
+.TP 7
+.BI "UseModes \*q" modesection\-id \*q
+Include the set of modes listed in the
+.B Modes
+section called
+.IR modesection\-id.
+This makes all of the modes defined in that section available for use by
+this monitor.
+.TP 7
+.BI "Mode \*q" name \*q
+This is an optional multi-line entry that can be used to provide
+definitions for video modes for the monitor.
+In most cases this isn't necessary because the built-in set of VESA standard
+modes will be sufficient.
+The
+.B Mode
+keyword indicates the start of a multi-line video mode description.
+The mode description is terminated with the
+.B EndMode
+keyword.
+The mode description consists of the following entries:
+.RS 7
+.TP 4
+.BI "DotClock " clock
+is the dot (pixel) clock rate to be used for the mode.
+.TP 4
+.BI "HTimings " "hdisp hsyncstart hsyncend htotal"
+specifies the horizontal timings for the mode.
+.TP 4
+.BI "VTimings " "vdisp vsyncstart vsyncend vtotal"
+specifies the vertical timings for the mode.
+.TP 4
+.BI "Flags \*q" flag \*q " ..."
+specifies an optional set of mode flags, each of which is a separate
+string in double quotes.
+.B \*qInterlace\*q
+indicates that the mode is interlaced.
+.B \*qDoubleScan\*q
+indicates a mode where each scanline is doubled.
+.B \*q+HSync\*q
+and
+.B \*q\-HSync\*q
+can be used to select the polarity of the HSync signal.
+.B \*q+VSync\*q
+and
+.B \*q\-VSync\*q
+can be used to select the polarity of the VSync signal.
+.B \*qComposite\*q
+can be used to specify composite sync on hardware where this is supported.
+Additionally, on some hardware,
+.B \*q+CSync\*q
+and
+.B \*q\-CSync\*q
+may be used to select the composite sync polarity.
+.TP 4
+.BI "HSkew " hskew
+specifies the number of pixels (towards the right edge of the screen) by
+which the display enable signal is to be skewed.
+Not all drivers use this information.
+This option might become necessary to override the default value supplied
+by the server (if any).
+\(lqRoving\(rq horizontal lines indicate this value needs to be increased.
+If the last few pixels on a scan line appear on the left of the screen,
+this value should be decreased.
+.TP 4
+.BI "VScan " vscan
+specifies the number of times each scanline is painted on the screen.
+Not all drivers use this information.
+Values less than 1 are treated as 1, which is the default.
+Generally, the
+.B \*qDoubleScan\*q
+.B Flag
+mentioned above doubles this value.
+.RE
+.TP 7
+.BI "ModeLine \*q" name \*q " mode\-description"
+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.
+In most cases this isn't necessary because the built\-in set of VESA
+standard modes will be sufficient.
+.PP
+.RS 7
+The
+.I mode\-description
+is in four sections, the first three of which are mandatory.
+The first is the dot (pixel) clock.
+This is a single number specifying the pixel clock rate for the mode in
+MHz.
+The second section is a list of four numbers specifying the horizontal
+timings.
+These numbers are the
+.IR hdisp ,
+.IR hsyncstart ,
+.IR hsyncend ,
+and
+.I htotal
+values.
+The third section is a list of four numbers specifying the vertical
+timings.
+These numbers are the
+.IR vdisp ,
+.IR vsyncstart ,
+.IR vsyncend ,
+and
+.I vtotal
+values.
+The final section is a list of flags specifying other characteristics of
+the mode.
+.B Interlace
+indicates that the mode is interlaced.
+.B DoubleScan
+indicates a mode where each scanline is doubled.
+.B +HSync
+and
+.B \-HSync
+can be used to select the polarity of the HSync signal.
+.B +VSync
+and
+.B \-VSync
+can be used to select the polarity of the VSync signal.
+.B Composite
+can be used to specify composite sync on hardware where this is supported.
+Additionally, on some hardware,
+.B +CSync
+and
+.B \-CSync
+may be used to select the composite sync polarity.
+The
+.B HSkew
+and
+.B VScan
+options mentioned above in the
+.B Modes
+entry description can also be used here.
+.RE
+.TP 7
+.BI "Option " "\*qDPMS\*q " \*qbool\*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
+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
+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
+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"
+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
+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
+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
+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
+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
+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
+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
+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
+This optional entry specifies the minimum dot clock, in kHz, that is supported
+by the monitor.
+.TP 7
+.BI "Option " "\*qMaxClock\*q " \*qfrequency\*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
+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
+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.
+(RandR 1.2-supporting drivers only)
+
+.SH "MODES SECTION"
+The config file may have multiple
+.B Modes
+sections, or none.
+These sections provide a way of defining sets of video modes independently
+of the
+.B Monitor
+sections.
+.B Monitor
+sections may include the definitions provided in these sections by
+using the
+.B UseModes
+keyword.
+In most cases the
+.B Modes
+sections are not necessary because the built\-in set of VESA standard modes
+will be sufficient.
+.PP
+.B Modes
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B "Section \*qModes\*q"
+.BI " Identifier \*q" name \*q
+.I " entries"
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+entry specifies the unique name for this set of mode descriptions.
+The other entries permitted in
+.B Modes
+sections are the
+.B Mode
+and
+.B ModeLine
+entries that are described above in the
+.B Monitor
+section.
+.SH "SCREEN SECTION"
+The config file may have multiple
+.B Screen
+sections.
+There must be at least one, for the \(lqscreen\(rq being used.
+A \(lqscreen\(rq represents the binding of a graphics device
+.RB ( Device
+section) and a monitor
+.RB ( Monitor
+section).
+A
+.B Screen
+section is considered \(lqactive\(rq if it is referenced by an active
+.B ServerLayout
+section or by the
+.B \-screen
+command line option.
+If neither of those is present, the first
+.B Screen
+section found in the config file is considered the active one.
+.PP
+.B Screen
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B "Section \*qScreen\*q"
+.BI " Identifier \*q" name \*q
+.BI " Device \*q" devid \*q
+.BI " Monitor \*q" monid \*q
+.I " entries"
+.I " ..."
+.BI " SubSection \*qDisplay\*q"
+.I " entries"
+.I " ...
+.B " EndSubSection"
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+and
+.B Device
+entries are mandatory.
+All others are optional.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this screen.
+The
+.B Screen
+section provides information specific to the whole screen, including
+screen\-specific
+.BR Options .
+In multi\-head configurations, there will be multiple active
+.B Screen
+sections, one for each head.
+The entries available
+for this section are:
+.TP 7
+.BI "Device \*q" device\-id \*q
+This mandatory entry specifies the
+.B Device
+section to be used for this screen.
+This is what ties a specific graphics card to a screen.
+The
+.I device\-id
+must match the
+.B Identifier
+of a
+.B Device
+section in the config file.
+.TP 7
+.BI "Monitor \*q" monitor\-id \*q
+specifies which monitor description is to be used for this screen.
+If a
+.B Monitor
+name is not specified, a default configuration is used.
+Currently the default configuration may not function as expected on all
+platforms.
+.TP 7
+.BI "VideoAdaptor \*q" xv\-id \*q
+specifies an optional Xv video adaptor description to be used with this
+screen.
+.TP 7
+.BI "DefaultDepth " depth
+specifies which color depth the server should use by default.
+The
+.B \-depth
+command line option can be used to override this.
+If neither is specified, the default depth is driver\-specific, but in most
+cases is 8.
+.TP 7
+.BI "DefaultFbBpp " bpp
+specifies which framebuffer layout to use by default.
+The
+.B \-fbbpp
+command line option can be used to override this.
+In most cases the driver will chose the best default value for this.
+The only case where there is even a choice in this value is for depth 24,
+where some hardware supports both a packed 24 bit framebuffer layout and a
+sparse 32 bit framebuffer layout.
+.TP 7
+.B Options
+Various
+.B Option
+flags may be specified in the
+.B Screen
+section.
+Some are driver\-specific and are described in the driver documentation.
+Others are driver\-independent, and will eventually be described here.
+.\" XXX These should really be in an xaa man page.
+.TP 7
+.BI "Option \*qAccel\*q"
+Enables XAA (X Acceleration Architecture), a mechanism that makes video cards'
+2D hardware acceleration available to the __xservername__ server.
+This option is on by default, but it may be necessary to turn it off if
+there are bugs in the driver.
+There are many options to disable specific accelerated operations, listed
+below.
+Note that disabling an operation will have no effect if the operation is
+not accelerated (whether due to lack of support in the hardware or in the
+driver).
+.TP 7
+.BI "Option \*qInitPrimary\*q \*q" boolean \*q
+Use the Int10 module to initialize the primary graphics card.
+Normally, only secondary cards are soft-booted using the Int10 module, as the
+primary card has already been initialized by the BIOS at boot time.
+Default: false.
+.TP 7
+.BI "Option \*qNoInt10\*q \*q" boolean \*q
+Disables the Int10 module, a module that uses the int10 call to the BIOS
+of the graphics card to initialize it.
+Default: false.
+.TP 7
+.BI "Option \*qNoMTRR\*q"
+Disables MTRR (Memory Type Range Register) support, a feature of modern
+processors which can improve video performance by a factor of up to 2.5.
+Some hardware has buggy MTRR support, and some video drivers have been
+known to exhibit problems when MTRR's are used.
+.TP 7
+.BI "Option \*qXaaNoCPUToScreenColorExpandFill\*q"
+Disables accelerated rectangular expansion blits from source patterns
+stored in system memory (using a memory\-mapped aperture).
+.TP 7
+.BI "Option \*qXaaNoColor8x8PatternFillRect\*q"
+Disables accelerated fills of a rectangular region with a full\-color
+pattern.
+.TP 7
+.BI "Option \*qXaaNoColor8x8PatternFillTrap\*q"
+Disables accelerated fills of a trapezoidal region with a full\-color
+pattern.
+.TP 7
+.BI "Option \*qXaaNoDashedBresenhamLine\*q"
+Disables accelerated dashed Bresenham line draws.
+.TP 7
+.BI "Option \*qXaaNoDashedTwoPointLine\*q"
+Disables accelerated dashed line draws between two arbitrary points.
+.TP 7
+.BI "Option \*qXaaNoImageWriteRect\*q"
+Disables accelerated transfers of full\-color rectangular patterns from
+system memory to video memory (using a memory\-mapped aperture).
+.TP 7
+.BI "Option \*qXaaNoMono8x8PatternFillRect\*q"
+Disables accelerated fills of a rectangular region with a monochrome
+pattern.
+.TP 7
+.BI "Option \*qXaaNoMono8x8PatternFillTrap\*q"
+Disables accelerated fills of a trapezoidal region with a monochrome
+pattern.
+.TP 7
+.BI "Option \*qXaaNoOffscreenPixmaps\*q"
+Disables accelerated draws into pixmaps stored in offscreen video memory.
+.TP 7
+.BI "Option \*qXaaNoPixmapCache\*q"
+Disables caching of patterns in offscreen video memory.
+.TP 7
+.BI "Option \*qXaaNoScanlineCPUToScreenColorExpandFill\*q"
+Disables accelerated rectangular expansion blits from source patterns
+stored in system memory (one scan line at a time).
+.TP 7
+.BI "Option \*qXaaNoScanlineImageWriteRect\*q"
+Disables accelerated transfers of full\-color rectangular patterns from
+system memory to video memory (one scan line at a time).
+.TP 7
+.BI "Option \*qXaaNoScreenToScreenColorExpandFill\*q"
+Disables accelerated rectangular expansion blits from source patterns
+stored in offscreen video memory.
+.TP 7
+.BI "Option \*qXaaNoScreenToScreenCopy\*q"
+Disables accelerated copies of rectangular regions from one part of
+video memory to another part of video memory.
+.TP 7
+.BI "Option \*qXaaNoSolidBresenhamLine\*q"
+Disables accelerated solid Bresenham line draws.
+.TP 7
+.BI "Option \*qXaaNoSolidFillRect\*q"
+Disables accelerated solid\-color fills of rectangles.
+.TP 7
+.BI "Option \*qXaaNoSolidFillTrap\*q"
+Disables accelerated solid\-color fills of Bresenham trapezoids.
+.TP 7
+.BI "Option \*qXaaNoSolidHorVertLine\*q"
+Disables accelerated solid horizontal and vertical line draws.
+.TP 7
+.BI "Option \*qXaaNoSolidTwoPointLine\*q"
+Disables accelerated solid line draws between two arbitrary points.
+.PP
+Each
+.B Screen
+section may optionally contain one or more
+.B Display
+subsections.
+Those subsections provide depth/fbbpp specific configuration information,
+and the one chosen depends on the depth and/or fbbpp that is being used for
+the screen.
+The
+.B Display
+subsection format is described in the section below.
+
+.SH "DISPLAY SUBSECTION"
+Each
+.B Screen
+section may have multiple
+.B Display
+subsections.
+The \(lqactive\(rq
+.B Display
+subsection is the first that matches the depth and/or fbbpp values being
+used, or failing that, the first that has neither a depth or fbbpp value
+specified.
+The
+.B Display
+subsections are optional.
+When there isn't one that matches the depth and/or fbbpp values being used,
+all the parameters that can be specified here fall back to their defaults.
+.PP
+.B Display
+subsections have the following format:
+.PP
+.RS 4
+.nf
+.B " SubSection \*qDisplay\*q"
+.BI " Depth " depth
+.I " entries"
+.I " ..."
+.B " EndSubSection"
+.fi
+.RE
+.TP 7
+.BI "Depth " depth
+This entry specifies what colour depth the
+.B Display
+subsection is to be used for.
+This entry is usually specified, but it may be omitted to create a match\-all
+.B Display
+subsection or when wishing to match only against the
+.B FbBpp
+parameter.
+The range of
+.I depth
+values that are allowed depends on the driver.
+Most drivers support 8, 15, 16 and 24.
+Some also support 1 and/or 4, and some may support other values (like 30).
+Note:
+.I depth
+means the number of bits in a pixel that are actually used to determine
+the pixel colour.
+32 is not a valid
+.I depth
+value.
+Most hardware that uses 32 bits per pixel only uses 24 of them to hold the
+colour information, which means that the colour depth is 24, not 32.
+.TP 7
+.BI "FbBpp " bpp
+This entry specifies the framebuffer format this
+.B Display
+subsection is to be used for.
+This entry is only needed when providing depth 24 configurations that allow
+a choice between a 24 bpp packed framebuffer format and a 32bpp sparse
+framebuffer format.
+In most cases this entry should not be used.
+.TP 7
+.BI "Weight " "red\-weight green\-weight blue\-weight"
+This optional entry specifies the relative RGB weighting to be used
+for a screen is being used at depth 16 for drivers that allow multiple
+formats.
+This may also be specified from the command line with the
+.B \-weight
+option (see
+.BR __xservername__(__appmansuffix__)).
+.TP 7
+.BI "Virtual " "xdim ydim"
+This optional entry specifies the virtual screen resolution to be used.
+.I xdim
+must be a multiple of either 8 or 16 for most drivers, and a multiple
+of 32 when running in monochrome mode.
+The given value will be rounded down if this is not the case.
+Video modes which are too large for the specified virtual size will be
+rejected.
+If this entry is not present, the virtual screen resolution will be set to
+accommodate all the valid video modes given in the
+.B Modes
+entry.
+Some drivers/hardware combinations do not support virtual screens.
+Refer to the appropriate driver\-specific documentation for details.
+.TP 7
+.BI "ViewPort " "x0 y0"
+This optional entry sets the upper left corner of the initial display.
+This is only relevant when the virtual screen resolution is different
+from the resolution of the initial video mode.
+If this entry is not given, then the initial display will be centered in
+the virtual display area.
+.TP 7
+.BI "Modes \*q" mode\-name \*q " ..."
+This optional entry specifies the list of video modes to use.
+Each
+.I mode\-name
+specified must be in double quotes.
+They must correspond to those specified or referenced in the appropriate
+.B Monitor
+section (including implicitly referenced built\-in VESA standard modes).
+The server will delete modes from this list which don't satisfy various
+requirements.
+The first valid mode in this list will be the default display mode for
+startup.
+The list of valid modes is converted internally into a circular list.
+It is possible to switch to the next mode with
+.B Ctrl+Alt+Keypad\-Plus
+and to the previous mode with
+.BR Ctrl+Alt+Keypad\-Minus .
+When this entry is omitted, the valid modes referenced by the appropriate
+.B Monitor
+section will be used. If the
+.B Monitor
+section contains no modes, then the selection will be taken from the
+built-in VESA standard modes.
+.TP 7
+.BI "Visual \*q" visual\-name \*q
+This optional entry sets the default root visual type.
+This may also be specified from the command line (see the
+.BR Xserver(__appmansuffix__)
+man page).
+The visual types available for depth 8 are (default is
+.BR PseudoColor ):
+.PP
+.RS 11
+.nf
+.B StaticGray
+.B GrayScale
+.B StaticColor
+.B PseudoColor
+.B TrueColor
+.B DirectColor
+.fi
+.RE
+.PP
+.RS 7
+The visual type available for the depths 15, 16 and 24 are (default is
+.BR TrueColor ):
+.PP
+.RS 4
+.nf
+.B TrueColor
+.B DirectColor
+.fi
+.RE
+.PP
+Not all drivers support
+.B DirectColor
+at these depths.
+.PP
+The visual types available for the depth 4 are (default is
+.BR StaticColor ):
+.PP
+.RS 4
+.nf
+.B StaticGray
+.B GrayScale
+.B StaticColor
+.B PseudoColor
+.fi
+.RE
+.PP
+The visual type available for the depth 1 (monochrome) is
+.BR StaticGray .
+.RE
+.TP 7
+.BI "Black " "red green blue"
+This optional entry allows the \(lqblack\(rq colour to be specified.
+This is only supported at depth 1.
+The default is black.
+.TP 7
+.BI "White " "red green blue"
+This optional entry allows the \(lqwhite\(rq colour to be specified.
+This is only supported at depth 1.
+The default is white.
+.TP 7
+.B Options
+Option flags may be specified in the
+.B Display
+subsections.
+These may include driver\-specific options and driver\-independent options.
+The former are described in the driver\-specific documentation.
+Some of the latter are described above in the section about the
+.B Screen
+section, and they may also be included here.
+.SH "SERVERLAYOUT SECTION"
+The config file may have multiple
+.B ServerLayout
+sections.
+A \(lqserver layout\(rq represents the binding of one or more screens
+.RB ( Screen
+sections) and one or more input devices
+.RB ( InputDevice
+sections) to form a complete configuration.
+In multi\-head configurations, it also specifies the relative layout of the
+heads.
+A
+.B ServerLayout
+section is considered \(lqactive\(rq if it is referenced by the
+.B \-layout
+command line option or by an
+.B "Option \*qDefaultServerLayout\*q"
+entry in the
+.B ServerFlags
+section (the former takes precedence over the latter).
+If those options are not used, the first
+.B ServerLayout
+section found in the config file is considered the active one.
+If no
+.B ServerLayout
+sections are present, the single active screen and two active (core)
+input devices are selected as described in the relevant sections above.
+.PP
+.B ServerLayout
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B "Section \*qServerLayout\*q"
+.BI " Identifier \*q" name \*q
+.BI " Screen \*q" screen\-id \*q
+.I " ..."
+.BI " InputDevice \*q" idev\-id \*q
+.I " ..."
+.I " options"
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.PP
+Each
+.B ServerLayout
+section must have an
+.B Identifier
+entry and at least one
+.B Screen
+entry.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this server layout.
+The
+.B ServerLayout
+section provides information specific to the whole session, including
+session\-specific
+.BR Options .
+The
+.B ServerFlags
+options (described above) may be specified here, and ones given here
+override those given in the
+.B ServerFlags
+section.
+.PP
+The entries that may be used in this section are described here.
+.TP 7
+.BI "Screen " "screen\-num" " \*qscreen\-id\*q " "position\-information"
+One of these entries must be given for each screen being used in
+a session.
+The
+.I screen\-id
+field is mandatory, and specifies the
+.B Screen
+section being referenced.
+The
+.I screen\-num
+field is optional, and may be used to specify the screen number
+in multi\-head configurations.
+When this field is omitted, the screens will be numbered in the order that
+they are listed in.
+The numbering starts from 0, and must be consecutive.
+The
+.I position\-information
+field describes the way multiple screens are positioned.
+There are a number of different ways that this information can be provided:
+.RS 7
+.TP 4
+.I "x y"
+.TP 4
+.BI "Absolute " "x y"
+These both specify that the upper left corner's coordinates are
+.RI ( x , y ).
+The
+.B Absolute
+keyword is optional.
+Some older versions of XFree86 (4.2 and earlier) don't recognise the
+.B Absolute
+keyword, so it's safest to just specify the coordinates without it.
+.TP 4
+.BI "RightOf \*q" screen\-id \*q
+.TP 4
+.BI "LeftOf \*q" screen\-id \*q
+.TP 4
+.BI "Above \*q" screen\-id \*q
+.TP 4
+.BI "Below \*q" screen\-id \*q
+.TP 4
+.BI "Relative \*q" screen\-id \*q " x y"
+These give the screen's location relative to another screen.
+The first four position the screen immediately to the right, left, above or
+below the other screen.
+When positioning to the right or left, the top edges are aligned.
+When positioning above or below, the left edges are aligned.
+The
+.B Relative
+form specifies the offset of the screen's origin (upper left corner)
+relative to the origin of another screen.
+.RE
+.TP 7
+.BI "InputDevice \*q" idev\-id "\*q \*q" option \*q " ..."
+One of these entries should be given for each input device being used in
+a session.
+Normally at least two are required, one each for the core pointer and
+keyboard devices.
+If either of those is missing, suitable
+.B InputDevice
+entries are searched for using the method described above in the
+.B INPUTDEVICE
+section. The
+.I idev\-id
+field is mandatory, and specifies the name of the
+.B InputDevice
+section being referenced.
+Multiple
+.I option
+fields may be specified, each in double quotes.
+The options permitted here are any that may also be given in the
+.B InputDevice
+sections.
+Normally only session\-specific input device options would be used here.
+The most commonly used options are:
+.PP
+.RS 11
+.nf
+.B \*qCorePointer\*q
+.B \*qCoreKeyboard\*q
+.B \*qSendCoreEvents\*q
+.fi
+.RE
+.PP
+.RS 7
+and the first two should normally be used to indicate the core pointer
+and core keyboard devices respectively.
+.RE
+.TP 7
+.B Options
+In addition to the following, any option permitted in the
+.B ServerFlags
+section may also be specified here.
+When the same option appears in both places, the value given here overrides
+the one given in the
+.B ServerFlags
+section.
+.TP 7
+.BI "Option \*qIsolateDevice\*q \*q" bus\-id \*q
+Restrict device resets to the specified
+.IR bus\-id .
+See the
+.B BusID
+option (described in
+.BR "DEVICE SECTION" ,
+above) for the format of the
+.I bus\-id
+parameter.
+This option overrides
+.BR SingleCard ,
+if specified.
+At present, only PCI devices can be isolated in this manner.
+.TP 7
+.BI "Option \*qSingleCard\*q \*q" boolean \*q
+As
+.BR IsolateDevice ,
+except that the bus ID of the first device in the layout is used.
+.PP
+Here is an example of a
+.B ServerLayout
+section for a dual headed configuration with two mice:
+.PP
+.RS 4
+.nf
+.B "Section \*qServerLayout\*q"
+.B " Identifier \*qLayout 1\*q"
+.B " Screen \*qMGA 1\*q"
+.B " Screen \*qMGA 2\*q RightOf \*qMGA 1\*q"
+.B " InputDevice \*qKeyboard 1\*q \*qCoreKeyboard\*q"
+.B " InputDevice \*qMouse 1\*q \*qCorePointer\*q"
+.B " InputDevice \*qMouse 2\*q \*qSendCoreEvents\*q"
+.B " Option \*qBlankTime\*q \*q5\*q"
+.B "EndSection"
+.fi
+.RE
+.SH "DRI SECTION"
+This optional section is used to provide some information for the
+Direct Rendering Infrastructure.
+Details about the format of this section can be found on-line at
+.IR <http://dri.freedesktop.org/> .
+.SH "VENDOR SECTION"
+The optional
+.B Vendor
+section may be used to provide vendor\-specific configuration information.
+Multiple
+.B Vendor
+sections may be present, and they may contain an
+.B Identifier
+entry and multiple
+.B Option
+flags.
+The data therein is not used in this release.
+.PP
+.SH "SEE ALSO"
+General:
+.BR X (__miscmansuffix__),
+.BR Xserver (__appmansuffix__),
+.BR __xservername__ (__appmansuffix__),
+.BR cvt (__appmansuffix__),
+.BR gtf (__appmansuffix__).
+.PP
+.B "Not all modules or interfaces are available on all platforms."
+.PP
+Display drivers:
+.BR apm (__drivermansuffix__),
+.BR ati (__drivermansuffix__),
+.BR chips (__drivermansuffix__),
+.BR cirrus (__drivermansuffix__),
+.BR cyrix (__drivermansuffix__),
+.BR fbdev (__drivermansuffix__),
+.BR glide (__drivermansuffix__),
+.BR glint (__drivermansuffix__),
+.BR i128 (__drivermansuffix__),
+.BR i740 (__drivermansuffix__),
+.BR imstt (__drivermansuffix__),
+.BR intel (__drivermansuffix__),
+.BR mga (__drivermansuffix__),
+.BR neomagic (__drivermansuffix__),
+.BR nv (__drivermansuffix__),
+.BR openchrome (__drivermansuffix__),
+.BR r128 (__drivermansuffix__),
+.BR radeon (__drivermansuffix__),
+.BR rendition (__drivermansuffix__),
+.BR savage (__drivermansuffix__),
+.BR s3virge (__drivermansuffix__),
+.BR siliconmotion (__drivermansuffix__),
+.BR sis (__drivermansuffix__),
+.BR sisusb (__drivermansuffix__),
+.BR sunbw2 (__drivermansuffix__),
+.BR suncg14 (__drivermansuffix__),
+.BR suncg3 (__drivermansuffix__),
+.BR suncg6 (__drivermansuffix__),
+.BR sunffb (__drivermansuffix__),
+.BR sunleo (__drivermansuffix__),
+.BR suntcx (__drivermansuffix__),
+.BR tdfx (__drivermansuffix__),
+.\" .BR tga (__drivermansuffix__),
+.BR trident (__drivermansuffix__),
+.BR tseng (__drivermansuffix__),
+.BR vesa (__drivermansuffix__),
+.BR vmware (__drivermansuffix__),
+.BR voodoo (__drivermansuffix__),
+.BR wsfb (__drivermansuffix__),
+.BR xgi (__drivermansuffix__),
+.BR xgixp (__drivermansuffix__).
+.PP
+Input drivers:
+.BR acecad (__drivermansuffix__),
+.BR citron (__drivermansuffix__),
+.BR elographics (__drivermansuffix__),
+.BR evdev (__drivermansuffix__),
+.BR fpit (__drivermansuffix__),
+.BR joystick (__drivermansuffix__),
+.BR kbd (__drivermansuffix__),
+.BR mousedrv (__drivermansuffix__),
+.BR mutouch (__drivermansuffix__),
+.BR penmount (__drivermansuffix__),
+.BR synaptics (__drivermansuffix__),
+.BR vmmouse (__drivermansuffix__),
+.BR void (__drivermansuffix__),
+.BR wacom (__drivermansuffix__).
+.PP
+Other modules and interfaces:
+.BR exa (__drivermansuffix__),
+.BR fbdevhw (__drivermansuffix__),
+.\" .BR shadowfb (__drivermansuffix__),
+.BR v4l (__drivermansuffix__).
+.br
+.SH AUTHORS
+This manual page was largely rewritten by David Dawes
+.IR <dawes@xfree86.org> .
diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.h b/xorg-server/hw/xfree86/modes/xf86Crtc.h
index 68a968cc2..5dfcec280 100644
--- a/xorg-server/hw/xfree86/modes/xf86Crtc.h
+++ b/xorg-server/hw/xfree86/modes/xf86Crtc.h
@@ -1,972 +1,972 @@
-/*
- * Copyright © 2006 Keith Packard
- *
- * 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 the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The 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 COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE 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.
- */
-#ifndef _XF86CRTC_H_
-#define _XF86CRTC_H_
-
-#include <edid.h>
-#include "randrstr.h"
-#if XF86_MODES_RENAME
-#include "xf86Rename.h"
-#endif
-#include "xf86Modes.h"
-#include "xf86Cursor.h"
-#include "xf86i2c.h"
-#include "damage.h"
-#include "picturestr.h"
-
-/* Compat definitions for older X Servers. */
-#ifndef M_T_PREFERRED
-#define M_T_PREFERRED 0x08
-#endif
-#ifndef M_T_DRIVER
-#define M_T_DRIVER 0x40
-#endif
-#ifndef M_T_USERPREF
-#define M_T_USERPREF 0x80
-#endif
-#ifndef HARDWARE_CURSOR_ARGB
-#define HARDWARE_CURSOR_ARGB 0x00004000
-#endif
-
-typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr;
-typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr;
-
-/* define a standard for connector types */
-typedef enum _xf86ConnectorType {
- XF86ConnectorNone,
- XF86ConnectorVGA,
- XF86ConnectorDVI_I,
- XF86ConnectorDVI_D,
- XF86ConnectorDVI_A,
- XF86ConnectorComposite,
- XF86ConnectorSvideo,
- XF86ConnectorComponent,
- XF86ConnectorLFP,
- XF86ConnectorProprietary,
- XF86ConnectorHDMI,
- XF86ConnectorDisplayPort,
-} xf86ConnectorType;
-
-typedef enum _xf86OutputStatus {
- XF86OutputStatusConnected,
- XF86OutputStatusDisconnected,
- XF86OutputStatusUnknown
-} xf86OutputStatus;
-
-typedef struct _xf86CrtcFuncs {
- /**
- * Turns the crtc on/off, or sets intermediate power levels if available.
- *
- * Unsupported intermediate modes drop to the lower power setting. If the
- * mode is DPMSModeOff, the crtc must be disabled sufficiently for it to
- * be safe to call mode_set.
- */
- void
- (*dpms)(xf86CrtcPtr crtc,
- int mode);
-
- /**
- * Saves the crtc's state for restoration on VT switch.
- */
- void
- (*save)(xf86CrtcPtr crtc);
-
- /**
- * Restore's the crtc's state at VT switch.
- */
- void
- (*restore)(xf86CrtcPtr crtc);
-
- /**
- * Lock CRTC prior to mode setting, mostly for DRI.
- * Returns whether unlock is needed
- */
- Bool
- (*lock) (xf86CrtcPtr crtc);
-
- /**
- * Unlock CRTC after mode setting, mostly for DRI
- */
- void
- (*unlock) (xf86CrtcPtr crtc);
-
- /**
- * Callback to adjust the mode to be set in the CRTC.
- *
- * This allows a CRTC to adjust the clock or even the entire set of
- * timings, which is used for panels with fixed timings or for
- * buses with clock limitations.
- */
- Bool
- (*mode_fixup)(xf86CrtcPtr crtc,
- DisplayModePtr mode,
- DisplayModePtr adjusted_mode);
-
- /**
- * Prepare CRTC for an upcoming mode set.
- */
- void
- (*prepare)(xf86CrtcPtr crtc);
-
- /**
- * Callback for setting up a video mode after fixups have been made.
- */
- void
- (*mode_set)(xf86CrtcPtr crtc,
- DisplayModePtr mode,
- DisplayModePtr adjusted_mode,
- int x, int y);
-
- /**
- * Commit mode changes to a CRTC
- */
- void
- (*commit)(xf86CrtcPtr crtc);
-
- /* Set the color ramps for the CRTC to the given values. */
- void
- (*gamma_set)(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
- int size);
-
- /**
- * Allocate the shadow area, delay the pixmap creation until needed
- */
- void *
- (*shadow_allocate) (xf86CrtcPtr crtc, int width, int height);
-
- /**
- * Create shadow pixmap for rotation support
- */
- PixmapPtr
- (*shadow_create) (xf86CrtcPtr crtc, void *data, int width, int height);
-
- /**
- * Destroy shadow pixmap
- */
- void
- (*shadow_destroy) (xf86CrtcPtr crtc, PixmapPtr pPixmap, void *data);
-
- /**
- * Set cursor colors
- */
- void
- (*set_cursor_colors) (xf86CrtcPtr crtc, int bg, int fg);
-
- /**
- * Set cursor position
- */
- void
- (*set_cursor_position) (xf86CrtcPtr crtc, int x, int y);
-
- /**
- * Show cursor
- */
- void
- (*show_cursor) (xf86CrtcPtr crtc);
-
- /**
- * Hide cursor
- */
- void
- (*hide_cursor) (xf86CrtcPtr crtc);
-
- /**
- * Load monochrome image
- */
- void
- (*load_cursor_image) (xf86CrtcPtr crtc, CARD8 *image);
-
- /**
- * Load ARGB image
- */
- void
- (*load_cursor_argb) (xf86CrtcPtr crtc, CARD32 *image);
-
- /**
- * Clean up driver-specific bits of the crtc
- */
- void
- (*destroy) (xf86CrtcPtr crtc);
-
- /**
- * Less fine-grained mode setting entry point for kernel modesetting
- */
- Bool
- (*set_mode_major)(xf86CrtcPtr crtc, DisplayModePtr mode,
- Rotation rotation, int x, int y);
-
- /**
- * Callback for panning. Doesn't change the mode.
- * Added in ABI version 2
- */
- void
- (*set_origin)(xf86CrtcPtr crtc, int x, int y);
-
-} xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
-
-#define XF86_CRTC_VERSION 3
-
-struct _xf86Crtc {
- /**
- * ABI versioning
- */
- int version;
-
- /**
- * Associated ScrnInfo
- */
- ScrnInfoPtr scrn;
-
- /**
- * Desired state of this CRTC
- *
- * Set when this CRTC should be driving one or more outputs
- */
- Bool enabled;
-
- /**
- * Active mode
- *
- * This reflects the mode as set in the CRTC currently
- * It will be cleared when the VT is not active or
- * during server startup
- */
- DisplayModeRec mode;
- Rotation rotation;
- PixmapPtr rotatedPixmap;
- void *rotatedData;
-
- /**
- * Position on screen
- *
- * Locates this CRTC within the frame buffer
- */
- int x, y;
-
- /**
- * Desired mode
- *
- * This is set to the requested mode, independent of
- * whether the VT is active. In particular, it receives
- * the startup configured mode and saves the active mode
- * on VT switch.
- */
- DisplayModeRec desiredMode;
- Rotation desiredRotation;
- int desiredX, desiredY;
-
- /** crtc-specific functions */
- const xf86CrtcFuncsRec *funcs;
-
- /**
- * Driver private
- *
- * Holds driver-private information
- */
- void *driver_private;
-
-#ifdef RANDR_12_INTERFACE
- /**
- * RandR crtc
- *
- * When RandR 1.2 is available, this
- * points at the associated crtc object
- */
- RRCrtcPtr randr_crtc;
-#else
- void *randr_crtc;
-#endif
-
- /**
- * Current cursor is ARGB
- */
- Bool cursor_argb;
- /**
- * Track whether cursor is within CRTC range
- */
- Bool cursor_in_range;
- /**
- * Track state of cursor associated with this CRTC
- */
- Bool cursor_shown;
-
- /**
- * Current transformation matrix
- */
- PictTransform crtc_to_framebuffer;
- /* framebuffer_to_crtc was removed in ABI 2 */
- struct pict_f_transform f_crtc_to_framebuffer; /* ABI 2 */
- struct pict_f_transform f_framebuffer_to_crtc; /* ABI 2 */
- PictFilterPtr filter; /* ABI 2 */
- xFixed *params; /* ABI 2 */
- int nparams; /* ABI 2 */
- int filter_width; /* ABI 2 */
- int filter_height; /* ABI 2 */
- Bool transform_in_use;
- RRTransformRec transform; /* ABI 2 */
- Bool transformPresent; /* ABI 2 */
- RRTransformRec desiredTransform; /* ABI 2 */
- Bool desiredTransformPresent; /* ABI 2 */
- /**
- * Bounding box in screen space
- */
- BoxRec bounds;
- /**
- * Panning:
- * TotalArea: total panning area, larger than CRTC's size
- * TrackingArea: Area of the pointer for which the CRTC is panned
- * border: Borders of the displayed CRTC area which induces panning if the pointer reaches them
- * Added in ABI version 2
- */
- BoxRec panningTotalArea;
- BoxRec panningTrackingArea;
- INT16 panningBorder[4];
-
- /**
- * Current gamma, especially useful after initial config.
- * Added in ABI version 3
- */
- CARD16 *gamma_red;
- CARD16 *gamma_green;
- CARD16 *gamma_blue;
- int gamma_size;
-
- /**
- * Actual state of this CRTC
- *
- * Set to TRUE after modesetting, set to FALSE if no outputs are connected
- * Added in ABI version 3
- */
- Bool active;
- /**
- * Clear the shadow
- */
- Bool shadowClear;
-};
-
-typedef struct _xf86OutputFuncs {
- /**
- * Called to allow the output a chance to create properties after the
- * RandR objects have been created.
- */
- void
- (*create_resources)(xf86OutputPtr output);
-
- /**
- * Turns the output on/off, or sets intermediate power levels if available.
- *
- * Unsupported intermediate modes drop to the lower power setting. If the
- * mode is DPMSModeOff, the output must be disabled, as the DPLL may be
- * disabled afterwards.
- */
- void
- (*dpms)(xf86OutputPtr output,
- int mode);
-
- /**
- * Saves the output's state for restoration on VT switch.
- */
- void
- (*save)(xf86OutputPtr output);
-
- /**
- * Restore's the output's state at VT switch.
- */
- void
- (*restore)(xf86OutputPtr output);
-
- /**
- * Callback for testing a video mode for a given output.
- *
- * This function should only check for cases where a mode can't be supported
- * on the output specifically, and not represent generic CRTC limitations.
- *
- * \return MODE_OK if the mode is valid, or another MODE_* otherwise.
- */
- int
- (*mode_valid)(xf86OutputPtr output,
- DisplayModePtr pMode);
-
- /**
- * Callback to adjust the mode to be set in the CRTC.
- *
- * This allows an output to adjust the clock or even the entire set of
- * timings, which is used for panels with fixed timings or for
- * buses with clock limitations.
- */
- Bool
- (*mode_fixup)(xf86OutputPtr output,
- DisplayModePtr mode,
- DisplayModePtr adjusted_mode);
-
- /**
- * Callback for preparing mode changes on an output
- */
- void
- (*prepare)(xf86OutputPtr output);
-
- /**
- * Callback for committing mode changes on an output
- */
- void
- (*commit)(xf86OutputPtr output);
-
- /**
- * Callback for setting up a video mode after fixups have been made.
- *
- * This is only called while the output is disabled. The dpms callback
- * must be all that's necessary for the output, to turn the output on
- * after this function is called.
- */
- void
- (*mode_set)(xf86OutputPtr output,
- DisplayModePtr mode,
- DisplayModePtr adjusted_mode);
-
- /**
- * Probe for a connected output, and return detect_status.
- */
- xf86OutputStatus
- (*detect)(xf86OutputPtr output);
-
- /**
- * Query the device for the modes it provides.
- *
- * This function may also update MonInfo, mm_width, and mm_height.
- *
- * \return singly-linked list of modes or NULL if no modes found.
- */
- DisplayModePtr
- (*get_modes)(xf86OutputPtr output);
-
-#ifdef RANDR_12_INTERFACE
- /**
- * Callback when an output's property has changed.
- */
- Bool
- (*set_property)(xf86OutputPtr output,
- Atom property,
- RRPropertyValuePtr value);
-#endif
-#ifdef RANDR_13_INTERFACE
- /**
- * Callback to get an updated property value
- */
- Bool
- (*get_property)(xf86OutputPtr output,
- Atom property);
-#endif
-#ifdef RANDR_GET_CRTC_INTERFACE
- /**
- * Callback to get current CRTC for a given output
- */
- xf86CrtcPtr
- (*get_crtc)(xf86OutputPtr output);
-#endif
- /**
- * Clean up driver-specific bits of the output
- */
- void
- (*destroy) (xf86OutputPtr output);
-} xf86OutputFuncsRec, *xf86OutputFuncsPtr;
-
-
-#define XF86_OUTPUT_VERSION 2
-
-struct _xf86Output {
- /**
- * ABI versioning
- */
- int version;
-
- /**
- * Associated ScrnInfo
- */
- ScrnInfoPtr scrn;
-
- /**
- * Currently connected crtc (if any)
- *
- * If this output is not in use, this field will be NULL.
- */
- xf86CrtcPtr crtc;
-
- /**
- * Possible CRTCs for this output as a mask of crtc indices
- */
- CARD32 possible_crtcs;
-
- /**
- * Possible outputs to share the same CRTC as a mask of output indices
- */
- CARD32 possible_clones;
-
- /**
- * Whether this output can support interlaced modes
- */
- Bool interlaceAllowed;
-
- /**
- * Whether this output can support double scan modes
- */
- Bool doubleScanAllowed;
-
- /**
- * List of available modes on this output.
- *
- * This should be the list from get_modes(), plus perhaps additional
- * compatible modes added later.
- */
- DisplayModePtr probed_modes;
-
- /**
- * Options parsed from the related monitor section
- */
- OptionInfoPtr options;
-
- /**
- * Configured monitor section
- */
- XF86ConfMonitorPtr conf_monitor;
-
- /**
- * Desired initial position
- */
- int initial_x, initial_y;
-
- /**
- * Desired initial rotation
- */
- Rotation initial_rotation;
-
- /**
- * Current connection status
- *
- * This indicates whether a monitor is known to be connected
- * to this output or not, or whether there is no way to tell
- */
- xf86OutputStatus status;
-
- /** EDID monitor information */
- xf86MonPtr MonInfo;
-
- /** subpixel order */
- int subpixel_order;
-
- /** Physical size of the currently attached output device. */
- int mm_width, mm_height;
-
- /** Output name */
- char *name;
-
- /** output-specific functions */
- const xf86OutputFuncsRec *funcs;
-
- /** driver private information */
- void *driver_private;
-
- /** Whether to use the old per-screen Monitor config section */
- Bool use_screen_monitor;
-
-#ifdef RANDR_12_INTERFACE
- /**
- * RandR 1.2 output structure.
- *
- * When RandR 1.2 is available, this points at the associated
- * RandR output structure and is created when this output is created
- */
- RROutputPtr randr_output;
-#else
- void *randr_output;
-#endif
- /**
- * Desired initial panning
- * Added in ABI version 2
- */
- BoxRec initialTotalArea;
- BoxRec initialTrackingArea;
- INT16 initialBorder[4];
-};
-
-typedef struct _xf86CrtcConfigFuncs {
- /**
- * Requests that the driver resize the screen.
- *
- * The driver is responsible for updating scrn->virtualX and scrn->virtualY.
- * If the requested size cannot be set, the driver should leave those values
- * alone and return FALSE.
- *
- * A naive driver that cannot reallocate the screen may simply change
- * virtual[XY]. A more advanced driver will want to also change the
- * devPrivate.ptr and devKind of the screen pixmap, update any offscreen
- * pixmaps it may have moved, and change pScrn->displayWidth.
- */
- Bool
- (*resize)(ScrnInfoPtr scrn,
- int width,
- int height);
-} xf86CrtcConfigFuncsRec, *xf86CrtcConfigFuncsPtr;
-
-typedef void (*xf86_crtc_notify_proc_ptr) (ScreenPtr pScreen);
-
-typedef struct _xf86CrtcConfig {
- int num_output;
- xf86OutputPtr *output;
- /**
- * compat_output is used whenever we deal
- * with legacy code that only understands a single
- * output. pScrn->modes will be loaded from this output,
- * adjust frame will whack this output, etc.
- */
- int compat_output;
-
- int num_crtc;
- xf86CrtcPtr *crtc;
-
- int minWidth, minHeight;
- int maxWidth, maxHeight;
-
- /* For crtc-based rotation */
- DamagePtr rotation_damage;
- Bool rotation_damage_registered;
-
- /* DGA */
- unsigned int dga_flags;
- unsigned long dga_address;
- DGAModePtr dga_modes;
- int dga_nmode;
- int dga_width, dga_height, dga_stride;
- DisplayModePtr dga_save_mode;
-
- const xf86CrtcConfigFuncsRec *funcs;
-
- CreateScreenResourcesProcPtr CreateScreenResources;
-
- CloseScreenProcPtr CloseScreen;
-
- /* Cursor information */
- xf86CursorInfoPtr cursor_info;
- CursorPtr cursor;
- CARD8 *cursor_image;
- Bool cursor_on;
- CARD32 cursor_fg, cursor_bg;
-
- /**
- * Options parsed from the related device section
- */
- OptionInfoPtr options;
-
- Bool debug_modes;
-
- /* wrap screen BlockHandler for rotation */
- ScreenBlockHandlerProcPtr BlockHandler;
-
- /* callback when crtc configuration changes */
- xf86_crtc_notify_proc_ptr xf86_crtc_notify;
-
-} xf86CrtcConfigRec, *xf86CrtcConfigPtr;
-
-extern _X_EXPORT int xf86CrtcConfigPrivateIndex;
-
-#define XF86_CRTC_CONFIG_PTR(p) ((xf86CrtcConfigPtr) ((p)->privates[xf86CrtcConfigPrivateIndex].ptr))
-
-static _X_INLINE xf86OutputPtr
-xf86CompatOutput(ScrnInfoPtr pScrn)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- return config->output[config->compat_output];
-}
-
-static _X_INLINE xf86CrtcPtr
-xf86CompatCrtc(ScrnInfoPtr pScrn)
-{
- xf86OutputPtr compat_output = xf86CompatOutput(pScrn);
- if (!compat_output)
- return NULL;
- return compat_output->crtc;
-}
-
-static _X_INLINE RRCrtcPtr
-xf86CompatRRCrtc(ScrnInfoPtr pScrn)
-{
- xf86CrtcPtr compat_crtc = xf86CompatCrtc(pScrn);
- if (!compat_crtc)
- return NULL;
- return compat_crtc->randr_crtc;
-}
-
-
-/*
- * Initialize xf86CrtcConfig structure
- */
-
-extern _X_EXPORT void
-xf86CrtcConfigInit (ScrnInfoPtr scrn,
- const xf86CrtcConfigFuncsRec *funcs);
-
-extern _X_EXPORT void
-xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
- int minWidth, int minHeight,
- int maxWidth, int maxHeight);
-
-/*
- * Crtc functions
- */
-extern _X_EXPORT xf86CrtcPtr
-xf86CrtcCreate (ScrnInfoPtr scrn,
- const xf86CrtcFuncsRec *funcs);
-
-extern _X_EXPORT void
-xf86CrtcDestroy (xf86CrtcPtr crtc);
-
-
-/**
- * Sets the given video mode on the given crtc
- */
-
-extern _X_EXPORT Bool
-xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
- RRTransformPtr transform, int x, int y);
-
-extern _X_EXPORT Bool
-xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
- int x, int y);
-
-extern _X_EXPORT void
-xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y);
-
-/*
- * Assign crtc rotation during mode set
- */
-extern _X_EXPORT Bool
-xf86CrtcRotate (xf86CrtcPtr crtc);
-
-/*
- * Clean up any rotation data, used when a crtc is turned off
- * as well as when rotation is disabled.
- */
-extern _X_EXPORT void
-xf86RotateDestroy (xf86CrtcPtr crtc);
-
-/*
- * free shadow memory allocated for all crtcs
- */
-extern _X_EXPORT void
-xf86RotateFreeShadow(ScrnInfoPtr pScrn);
-
-/*
- * Clean up rotation during CloseScreen
- */
-extern _X_EXPORT void
-xf86RotateCloseScreen (ScreenPtr pScreen);
-
-/**
- * Return whether any output is assigned to the crtc
- */
-extern _X_EXPORT Bool
-xf86CrtcInUse (xf86CrtcPtr crtc);
-
-/*
- * Output functions
- */
-extern _X_EXPORT xf86OutputPtr
-xf86OutputCreate (ScrnInfoPtr scrn,
- const xf86OutputFuncsRec *funcs,
- const char *name);
-
-extern _X_EXPORT void
-xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor);
-
-extern _X_EXPORT Bool
-xf86OutputRename (xf86OutputPtr output, const char *name);
-
-extern _X_EXPORT void
-xf86OutputDestroy (xf86OutputPtr output);
-
-extern _X_EXPORT void
-xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY);
-
-extern _X_EXPORT void
-xf86SetScrnInfoModes (ScrnInfoPtr pScrn);
-
-#ifdef RANDR_13_INTERFACE
-# define ScreenInitRetType int
-#else
-# define ScreenInitRetType Bool
-#endif
-
-extern _X_EXPORT ScreenInitRetType
-xf86CrtcScreenInit (ScreenPtr pScreen);
-
-extern _X_EXPORT Bool
-xf86InitialConfiguration (ScrnInfoPtr pScrn, Bool canGrow);
-
-extern _X_EXPORT void
-xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
-
-extern _X_EXPORT Bool
-xf86SaveScreen(ScreenPtr pScreen, int mode);
-
-extern _X_EXPORT void
-xf86DisableUnusedFunctions(ScrnInfoPtr pScrn);
-
-extern _X_EXPORT DisplayModePtr
-xf86OutputFindClosestMode (xf86OutputPtr output, DisplayModePtr desired);
-
-extern _X_EXPORT Bool
-xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation);
-
-/**
- * Set the EDID information for the specified output
- */
-extern _X_EXPORT void
-xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon);
-
-/**
- * Return the list of modes supported by the EDID information
- * stored in 'output'
- */
-extern _X_EXPORT DisplayModePtr
-xf86OutputGetEDIDModes (xf86OutputPtr output);
-
-extern _X_EXPORT xf86MonPtr
-xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus);
-
-/**
- * Initialize dga for this screen
- */
-
-#ifdef XFreeXDGA
-extern _X_EXPORT Bool
-xf86DiDGAInit (ScreenPtr pScreen, unsigned long dga_address);
-
-/* this is the real function, used only internally */
-_X_INTERNAL Bool
-_xf86_di_dga_init_internal (ScreenPtr pScreen);
-
-/**
- * Re-initialize dga for this screen (as when the set of modes changes)
- */
-
-extern _X_EXPORT Bool
-xf86DiDGAReInit (ScreenPtr pScreen);
-#endif
-
-/* This is the real function, used only internally */
-_X_INTERNAL Bool
-_xf86_di_dga_reinit_internal (ScreenPtr pScreen);
-
-/*
- * Set the subpixel order reported for the screen using
- * the information from the outputs
- */
-
-extern _X_EXPORT void
-xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen);
-
-/*
- * Get a standard string name for a connector type
- */
-extern _X_EXPORT char *
-xf86ConnectorGetName(xf86ConnectorType connector);
-
-/*
- * Using the desired mode information in each crtc, set
- * modes (used in EnterVT functions, or at server startup)
- */
-
-extern _X_EXPORT Bool
-xf86SetDesiredModes (ScrnInfoPtr pScrn);
-
-/**
- * Initialize the CRTC-based cursor code. CRTC function vectors must
- * contain relevant cursor setting functions.
- *
- * Driver should call this from ScreenInit function
- */
-extern _X_EXPORT Bool
-xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags);
-
-/**
- * Called when anything on the screen is reconfigured.
- *
- * Reloads cursor images as needed, then adjusts cursor positions.
- *
- * Driver should call this from crtc commit function.
- */
-extern _X_EXPORT void
-xf86_reload_cursors (ScreenPtr screen);
-
-/**
- * Called from EnterVT to turn the cursors back on
- */
-extern _X_EXPORT void
-xf86_show_cursors (ScrnInfoPtr scrn);
-
-/**
- * Called by the driver to turn cursors off
- */
-extern _X_EXPORT void
-xf86_hide_cursors (ScrnInfoPtr scrn);
-
-/**
- * Clean up CRTC-based cursor code. Driver must call this at CloseScreen time.
- */
-extern _X_EXPORT void
-xf86_cursors_fini (ScreenPtr screen);
-
-/*
- * For overlay video, compute the relevant CRTC and
- * clip video to that.
- * wraps xf86XVClipVideoHelper()
- */
-
-extern _X_EXPORT Bool
-xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn,
- xf86CrtcPtr *crtc_ret,
- xf86CrtcPtr desired_crtc,
- BoxPtr dst,
- INT32 *xa,
- INT32 *xb,
- INT32 *ya,
- INT32 *yb,
- RegionPtr reg,
- INT32 width,
- INT32 height);
-
-extern _X_EXPORT xf86_crtc_notify_proc_ptr
-xf86_wrap_crtc_notify (ScreenPtr pScreen, xf86_crtc_notify_proc_ptr new);
-
-extern _X_EXPORT void
-xf86_unwrap_crtc_notify(ScreenPtr pScreen, xf86_crtc_notify_proc_ptr old);
-
-extern _X_EXPORT void
-xf86_crtc_notify(ScreenPtr pScreen);
-
-/**
- * Gamma
- */
-
-extern _X_EXPORT Bool
-xf86_crtc_supports_gamma(ScrnInfoPtr pScrn);
-
-#endif /* _XF86CRTC_H_ */
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * 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 the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The 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 COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE 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.
+ */
+#ifndef _XF86CRTC_H_
+#define _XF86CRTC_H_
+
+#include <edid.h>
+#include "randrstr.h"
+#if XF86_MODES_RENAME
+#include "xf86Rename.h"
+#endif
+#include "xf86Modes.h"
+#include "xf86Cursor.h"
+#include "xf86i2c.h"
+#include "damage.h"
+#include "picturestr.h"
+
+/* Compat definitions for older X Servers. */
+#ifndef M_T_PREFERRED
+#define M_T_PREFERRED 0x08
+#endif
+#ifndef M_T_DRIVER
+#define M_T_DRIVER 0x40
+#endif
+#ifndef M_T_USERPREF
+#define M_T_USERPREF 0x80
+#endif
+#ifndef HARDWARE_CURSOR_ARGB
+#define HARDWARE_CURSOR_ARGB 0x00004000
+#endif
+
+typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr;
+typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr;
+
+/* define a standard for connector types */
+typedef enum _xf86ConnectorType {
+ XF86ConnectorNone,
+ XF86ConnectorVGA,
+ XF86ConnectorDVI_I,
+ XF86ConnectorDVI_D,
+ XF86ConnectorDVI_A,
+ XF86ConnectorComposite,
+ XF86ConnectorSvideo,
+ XF86ConnectorComponent,
+ XF86ConnectorLFP,
+ XF86ConnectorProprietary,
+ XF86ConnectorHDMI,
+ XF86ConnectorDisplayPort,
+} xf86ConnectorType;
+
+typedef enum _xf86OutputStatus {
+ XF86OutputStatusConnected,
+ XF86OutputStatusDisconnected,
+ XF86OutputStatusUnknown
+} xf86OutputStatus;
+
+typedef struct _xf86CrtcFuncs {
+ /**
+ * Turns the crtc on/off, or sets intermediate power levels if available.
+ *
+ * Unsupported intermediate modes drop to the lower power setting. If the
+ * mode is DPMSModeOff, the crtc must be disabled sufficiently for it to
+ * be safe to call mode_set.
+ */
+ void
+ (*dpms)(xf86CrtcPtr crtc,
+ int mode);
+
+ /**
+ * Saves the crtc's state for restoration on VT switch.
+ */
+ void
+ (*save)(xf86CrtcPtr crtc);
+
+ /**
+ * Restore's the crtc's state at VT switch.
+ */
+ void
+ (*restore)(xf86CrtcPtr crtc);
+
+ /**
+ * Lock CRTC prior to mode setting, mostly for DRI.
+ * Returns whether unlock is needed
+ */
+ Bool
+ (*lock) (xf86CrtcPtr crtc);
+
+ /**
+ * Unlock CRTC after mode setting, mostly for DRI
+ */
+ void
+ (*unlock) (xf86CrtcPtr crtc);
+
+ /**
+ * Callback to adjust the mode to be set in the CRTC.
+ *
+ * This allows a CRTC to adjust the clock or even the entire set of
+ * timings, which is used for panels with fixed timings or for
+ * buses with clock limitations.
+ */
+ Bool
+ (*mode_fixup)(xf86CrtcPtr crtc,
+ DisplayModePtr mode,
+ DisplayModePtr adjusted_mode);
+
+ /**
+ * Prepare CRTC for an upcoming mode set.
+ */
+ void
+ (*prepare)(xf86CrtcPtr crtc);
+
+ /**
+ * Callback for setting up a video mode after fixups have been made.
+ */
+ void
+ (*mode_set)(xf86CrtcPtr crtc,
+ DisplayModePtr mode,
+ DisplayModePtr adjusted_mode,
+ int x, int y);
+
+ /**
+ * Commit mode changes to a CRTC
+ */
+ void
+ (*commit)(xf86CrtcPtr crtc);
+
+ /* Set the color ramps for the CRTC to the given values. */
+ void
+ (*gamma_set)(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
+ int size);
+
+ /**
+ * Allocate the shadow area, delay the pixmap creation until needed
+ */
+ void *
+ (*shadow_allocate) (xf86CrtcPtr crtc, int width, int height);
+
+ /**
+ * Create shadow pixmap for rotation support
+ */
+ PixmapPtr
+ (*shadow_create) (xf86CrtcPtr crtc, void *data, int width, int height);
+
+ /**
+ * Destroy shadow pixmap
+ */
+ void
+ (*shadow_destroy) (xf86CrtcPtr crtc, PixmapPtr pPixmap, void *data);
+
+ /**
+ * Set cursor colors
+ */
+ void
+ (*set_cursor_colors) (xf86CrtcPtr crtc, int bg, int fg);
+
+ /**
+ * Set cursor position
+ */
+ void
+ (*set_cursor_position) (xf86CrtcPtr crtc, int x, int y);
+
+ /**
+ * Show cursor
+ */
+ void
+ (*show_cursor) (xf86CrtcPtr crtc);
+
+ /**
+ * Hide cursor
+ */
+ void
+ (*hide_cursor) (xf86CrtcPtr crtc);
+
+ /**
+ * Load monochrome image
+ */
+ void
+ (*load_cursor_image) (xf86CrtcPtr crtc, CARD8 *image);
+
+ /**
+ * Load ARGB image
+ */
+ void
+ (*load_cursor_argb) (xf86CrtcPtr crtc, CARD32 *image);
+
+ /**
+ * Clean up driver-specific bits of the crtc
+ */
+ void
+ (*destroy) (xf86CrtcPtr crtc);
+
+ /**
+ * Less fine-grained mode setting entry point for kernel modesetting
+ */
+ Bool
+ (*set_mode_major)(xf86CrtcPtr crtc, DisplayModePtr mode,
+ Rotation rotation, int x, int y);
+
+ /**
+ * Callback for panning. Doesn't change the mode.
+ * Added in ABI version 2
+ */
+ void
+ (*set_origin)(xf86CrtcPtr crtc, int x, int y);
+
+} xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
+
+#define XF86_CRTC_VERSION 3
+
+struct _xf86Crtc {
+ /**
+ * ABI versioning
+ */
+ int version;
+
+ /**
+ * Associated ScrnInfo
+ */
+ ScrnInfoPtr scrn;
+
+ /**
+ * Desired state of this CRTC
+ *
+ * Set when this CRTC should be driving one or more outputs
+ */
+ Bool enabled;
+
+ /**
+ * Active mode
+ *
+ * This reflects the mode as set in the CRTC currently
+ * It will be cleared when the VT is not active or
+ * during server startup
+ */
+ DisplayModeRec mode;
+ Rotation rotation;
+ PixmapPtr rotatedPixmap;
+ void *rotatedData;
+
+ /**
+ * Position on screen
+ *
+ * Locates this CRTC within the frame buffer
+ */
+ int x, y;
+
+ /**
+ * Desired mode
+ *
+ * This is set to the requested mode, independent of
+ * whether the VT is active. In particular, it receives
+ * the startup configured mode and saves the active mode
+ * on VT switch.
+ */
+ DisplayModeRec desiredMode;
+ Rotation desiredRotation;
+ int desiredX, desiredY;
+
+ /** crtc-specific functions */
+ const xf86CrtcFuncsRec *funcs;
+
+ /**
+ * Driver private
+ *
+ * Holds driver-private information
+ */
+ void *driver_private;
+
+#ifdef RANDR_12_INTERFACE
+ /**
+ * RandR crtc
+ *
+ * When RandR 1.2 is available, this
+ * points at the associated crtc object
+ */
+ RRCrtcPtr randr_crtc;
+#else
+ void *randr_crtc;
+#endif
+
+ /**
+ * Current cursor is ARGB
+ */
+ Bool cursor_argb;
+ /**
+ * Track whether cursor is within CRTC range
+ */
+ Bool cursor_in_range;
+ /**
+ * Track state of cursor associated with this CRTC
+ */
+ Bool cursor_shown;
+
+ /**
+ * Current transformation matrix
+ */
+ PictTransform crtc_to_framebuffer;
+ /* framebuffer_to_crtc was removed in ABI 2 */
+ struct pict_f_transform f_crtc_to_framebuffer; /* ABI 2 */
+ struct pict_f_transform f_framebuffer_to_crtc; /* ABI 2 */
+ PictFilterPtr filter; /* ABI 2 */
+ xFixed *params; /* ABI 2 */
+ int nparams; /* ABI 2 */
+ int filter_width; /* ABI 2 */
+ int filter_height; /* ABI 2 */
+ Bool transform_in_use;
+ RRTransformRec transform; /* ABI 2 */
+ Bool transformPresent; /* ABI 2 */
+ RRTransformRec desiredTransform; /* ABI 2 */
+ Bool desiredTransformPresent; /* ABI 2 */
+ /**
+ * Bounding box in screen space
+ */
+ BoxRec bounds;
+ /**
+ * Panning:
+ * TotalArea: total panning area, larger than CRTC's size
+ * TrackingArea: Area of the pointer for which the CRTC is panned
+ * border: Borders of the displayed CRTC area which induces panning if the pointer reaches them
+ * Added in ABI version 2
+ */
+ BoxRec panningTotalArea;
+ BoxRec panningTrackingArea;
+ INT16 panningBorder[4];
+
+ /**
+ * Current gamma, especially useful after initial config.
+ * Added in ABI version 3
+ */
+ CARD16 *gamma_red;
+ CARD16 *gamma_green;
+ CARD16 *gamma_blue;
+ int gamma_size;
+
+ /**
+ * Actual state of this CRTC
+ *
+ * Set to TRUE after modesetting, set to FALSE if no outputs are connected
+ * Added in ABI version 3
+ */
+ Bool active;
+ /**
+ * Clear the shadow
+ */
+ Bool shadowClear;
+};
+
+typedef struct _xf86OutputFuncs {
+ /**
+ * Called to allow the output a chance to create properties after the
+ * RandR objects have been created.
+ */
+ void
+ (*create_resources)(xf86OutputPtr output);
+
+ /**
+ * Turns the output on/off, or sets intermediate power levels if available.
+ *
+ * Unsupported intermediate modes drop to the lower power setting. If the
+ * mode is DPMSModeOff, the output must be disabled, as the DPLL may be
+ * disabled afterwards.
+ */
+ void
+ (*dpms)(xf86OutputPtr output,
+ int mode);
+
+ /**
+ * Saves the output's state for restoration on VT switch.
+ */
+ void
+ (*save)(xf86OutputPtr output);
+
+ /**
+ * Restore's the output's state at VT switch.
+ */
+ void
+ (*restore)(xf86OutputPtr output);
+
+ /**
+ * Callback for testing a video mode for a given output.
+ *
+ * This function should only check for cases where a mode can't be supported
+ * on the output specifically, and not represent generic CRTC limitations.
+ *
+ * \return MODE_OK if the mode is valid, or another MODE_* otherwise.
+ */
+ int
+ (*mode_valid)(xf86OutputPtr output,
+ DisplayModePtr pMode);
+
+ /**
+ * Callback to adjust the mode to be set in the CRTC.
+ *
+ * This allows an output to adjust the clock or even the entire set of
+ * timings, which is used for panels with fixed timings or for
+ * buses with clock limitations.
+ */
+ Bool
+ (*mode_fixup)(xf86OutputPtr output,
+ DisplayModePtr mode,
+ DisplayModePtr adjusted_mode);
+
+ /**
+ * Callback for preparing mode changes on an output
+ */
+ void
+ (*prepare)(xf86OutputPtr output);
+
+ /**
+ * Callback for committing mode changes on an output
+ */
+ void
+ (*commit)(xf86OutputPtr output);
+
+ /**
+ * Callback for setting up a video mode after fixups have been made.
+ *
+ * This is only called while the output is disabled. The dpms callback
+ * must be all that's necessary for the output, to turn the output on
+ * after this function is called.
+ */
+ void
+ (*mode_set)(xf86OutputPtr output,
+ DisplayModePtr mode,
+ DisplayModePtr adjusted_mode);
+
+ /**
+ * Probe for a connected output, and return detect_status.
+ */
+ xf86OutputStatus
+ (*detect)(xf86OutputPtr output);
+
+ /**
+ * Query the device for the modes it provides.
+ *
+ * This function may also update MonInfo, mm_width, and mm_height.
+ *
+ * \return singly-linked list of modes or NULL if no modes found.
+ */
+ DisplayModePtr
+ (*get_modes)(xf86OutputPtr output);
+
+#ifdef RANDR_12_INTERFACE
+ /**
+ * Callback when an output's property has changed.
+ */
+ Bool
+ (*set_property)(xf86OutputPtr output,
+ Atom property,
+ RRPropertyValuePtr value);
+#endif
+#ifdef RANDR_13_INTERFACE
+ /**
+ * Callback to get an updated property value
+ */
+ Bool
+ (*get_property)(xf86OutputPtr output,
+ Atom property);
+#endif
+#ifdef RANDR_GET_CRTC_INTERFACE
+ /**
+ * Callback to get current CRTC for a given output
+ */
+ xf86CrtcPtr
+ (*get_crtc)(xf86OutputPtr output);
+#endif
+ /**
+ * Clean up driver-specific bits of the output
+ */
+ void
+ (*destroy) (xf86OutputPtr output);
+} xf86OutputFuncsRec, *xf86OutputFuncsPtr;
+
+
+#define XF86_OUTPUT_VERSION 2
+
+struct _xf86Output {
+ /**
+ * ABI versioning
+ */
+ int version;
+
+ /**
+ * Associated ScrnInfo
+ */
+ ScrnInfoPtr scrn;
+
+ /**
+ * Currently connected crtc (if any)
+ *
+ * If this output is not in use, this field will be NULL.
+ */
+ xf86CrtcPtr crtc;
+
+ /**
+ * Possible CRTCs for this output as a mask of crtc indices
+ */
+ CARD32 possible_crtcs;
+
+ /**
+ * Possible outputs to share the same CRTC as a mask of output indices
+ */
+ CARD32 possible_clones;
+
+ /**
+ * Whether this output can support interlaced modes
+ */
+ Bool interlaceAllowed;
+
+ /**
+ * Whether this output can support double scan modes
+ */
+ Bool doubleScanAllowed;
+
+ /**
+ * List of available modes on this output.
+ *
+ * This should be the list from get_modes(), plus perhaps additional
+ * compatible modes added later.
+ */
+ DisplayModePtr probed_modes;
+
+ /**
+ * Options parsed from the related monitor section
+ */
+ OptionInfoPtr options;
+
+ /**
+ * Configured monitor section
+ */
+ XF86ConfMonitorPtr conf_monitor;
+
+ /**
+ * Desired initial position
+ */
+ int initial_x, initial_y;
+
+ /**
+ * Desired initial rotation
+ */
+ Rotation initial_rotation;
+
+ /**
+ * Current connection status
+ *
+ * This indicates whether a monitor is known to be connected
+ * to this output or not, or whether there is no way to tell
+ */
+ xf86OutputStatus status;
+
+ /** EDID monitor information */
+ xf86MonPtr MonInfo;
+
+ /** subpixel order */
+ int subpixel_order;
+
+ /** Physical size of the currently attached output device. */
+ int mm_width, mm_height;
+
+ /** Output name */
+ char *name;
+
+ /** output-specific functions */
+ const xf86OutputFuncsRec *funcs;
+
+ /** driver private information */
+ void *driver_private;
+
+ /** Whether to use the old per-screen Monitor config section */
+ Bool use_screen_monitor;
+
+#ifdef RANDR_12_INTERFACE
+ /**
+ * RandR 1.2 output structure.
+ *
+ * When RandR 1.2 is available, this points at the associated
+ * RandR output structure and is created when this output is created
+ */
+ RROutputPtr randr_output;
+#else
+ void *randr_output;
+#endif
+ /**
+ * Desired initial panning
+ * Added in ABI version 2
+ */
+ BoxRec initialTotalArea;
+ BoxRec initialTrackingArea;
+ INT16 initialBorder[4];
+};
+
+typedef struct _xf86CrtcConfigFuncs {
+ /**
+ * Requests that the driver resize the screen.
+ *
+ * The driver is responsible for updating scrn->virtualX and scrn->virtualY.
+ * If the requested size cannot be set, the driver should leave those values
+ * alone and return FALSE.
+ *
+ * A naive driver that cannot reallocate the screen may simply change
+ * virtual[XY]. A more advanced driver will want to also change the
+ * devPrivate.ptr and devKind of the screen pixmap, update any offscreen
+ * pixmaps it may have moved, and change pScrn->displayWidth.
+ */
+ Bool
+ (*resize)(ScrnInfoPtr scrn,
+ int width,
+ int height);
+} xf86CrtcConfigFuncsRec, *xf86CrtcConfigFuncsPtr;
+
+typedef void (*xf86_crtc_notify_proc_ptr) (ScreenPtr pScreen);
+
+typedef struct _xf86CrtcConfig {
+ int num_output;
+ xf86OutputPtr *output;
+ /**
+ * compat_output is used whenever we deal
+ * with legacy code that only understands a single
+ * output. pScrn->modes will be loaded from this output,
+ * adjust frame will whack this output, etc.
+ */
+ int compat_output;
+
+ int num_crtc;
+ xf86CrtcPtr *crtc;
+
+ int minWidth, minHeight;
+ int maxWidth, maxHeight;
+
+ /* For crtc-based rotation */
+ DamagePtr rotation_damage;
+ Bool rotation_damage_registered;
+
+ /* DGA */
+ unsigned int dga_flags;
+ unsigned long dga_address;
+ DGAModePtr dga_modes;
+ int dga_nmode;
+ int dga_width, dga_height, dga_stride;
+ DisplayModePtr dga_save_mode;
+
+ const xf86CrtcConfigFuncsRec *funcs;
+
+ CreateScreenResourcesProcPtr CreateScreenResources;
+
+ CloseScreenProcPtr CloseScreen;
+
+ /* Cursor information */
+ xf86CursorInfoPtr cursor_info;
+ CursorPtr cursor;
+ CARD8 *cursor_image;
+ Bool cursor_on;
+ CARD32 cursor_fg, cursor_bg;
+
+ /**
+ * Options parsed from the related device section
+ */
+ OptionInfoPtr options;
+
+ Bool debug_modes;
+
+ /* wrap screen BlockHandler for rotation */
+ ScreenBlockHandlerProcPtr BlockHandler;
+
+ /* callback when crtc configuration changes */
+ xf86_crtc_notify_proc_ptr xf86_crtc_notify;
+
+} xf86CrtcConfigRec, *xf86CrtcConfigPtr;
+
+extern _X_EXPORT int xf86CrtcConfigPrivateIndex;
+
+#define XF86_CRTC_CONFIG_PTR(p) ((xf86CrtcConfigPtr) ((p)->privates[xf86CrtcConfigPrivateIndex].ptr))
+
+static _X_INLINE xf86OutputPtr
+xf86CompatOutput(ScrnInfoPtr pScrn)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ return config->output[config->compat_output];
+}
+
+static _X_INLINE xf86CrtcPtr
+xf86CompatCrtc(ScrnInfoPtr pScrn)
+{
+ xf86OutputPtr compat_output = xf86CompatOutput(pScrn);
+ if (!compat_output)
+ return NULL;
+ return compat_output->crtc;
+}
+
+static _X_INLINE RRCrtcPtr
+xf86CompatRRCrtc(ScrnInfoPtr pScrn)
+{
+ xf86CrtcPtr compat_crtc = xf86CompatCrtc(pScrn);
+ if (!compat_crtc)
+ return NULL;
+ return compat_crtc->randr_crtc;
+}
+
+
+/*
+ * Initialize xf86CrtcConfig structure
+ */
+
+extern _X_EXPORT void
+xf86CrtcConfigInit (ScrnInfoPtr scrn,
+ const xf86CrtcConfigFuncsRec *funcs);
+
+extern _X_EXPORT void
+xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
+ int minWidth, int minHeight,
+ int maxWidth, int maxHeight);
+
+/*
+ * Crtc functions
+ */
+extern _X_EXPORT xf86CrtcPtr
+xf86CrtcCreate (ScrnInfoPtr scrn,
+ const xf86CrtcFuncsRec *funcs);
+
+extern _X_EXPORT void
+xf86CrtcDestroy (xf86CrtcPtr crtc);
+
+
+/**
+ * Sets the given video mode on the given crtc
+ */
+
+extern _X_EXPORT Bool
+xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+ RRTransformPtr transform, int x, int y);
+
+extern _X_EXPORT Bool
+xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+ int x, int y);
+
+extern _X_EXPORT void
+xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y);
+
+/*
+ * Assign crtc rotation during mode set
+ */
+extern _X_EXPORT Bool
+xf86CrtcRotate (xf86CrtcPtr crtc);
+
+/*
+ * Clean up any rotation data, used when a crtc is turned off
+ * as well as when rotation is disabled.
+ */
+extern _X_EXPORT void
+xf86RotateDestroy (xf86CrtcPtr crtc);
+
+/*
+ * free shadow memory allocated for all crtcs
+ */
+extern _X_EXPORT void
+xf86RotateFreeShadow(ScrnInfoPtr pScrn);
+
+/*
+ * Clean up rotation during CloseScreen
+ */
+extern _X_EXPORT void
+xf86RotateCloseScreen (ScreenPtr pScreen);
+
+/**
+ * Return whether any output is assigned to the crtc
+ */
+extern _X_EXPORT Bool
+xf86CrtcInUse (xf86CrtcPtr crtc);
+
+/*
+ * Output functions
+ */
+extern _X_EXPORT xf86OutputPtr
+xf86OutputCreate (ScrnInfoPtr scrn,
+ const xf86OutputFuncsRec *funcs,
+ const char *name);
+
+extern _X_EXPORT void
+xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor);
+
+extern _X_EXPORT Bool
+xf86OutputRename (xf86OutputPtr output, const char *name);
+
+extern _X_EXPORT void
+xf86OutputDestroy (xf86OutputPtr output);
+
+extern _X_EXPORT void
+xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY);
+
+extern _X_EXPORT void
+xf86SetScrnInfoModes (ScrnInfoPtr pScrn);
+
+#ifdef RANDR_13_INTERFACE
+# define ScreenInitRetType int
+#else
+# define ScreenInitRetType Bool
+#endif
+
+extern _X_EXPORT ScreenInitRetType
+xf86CrtcScreenInit (ScreenPtr pScreen);
+
+extern _X_EXPORT Bool
+xf86InitialConfiguration (ScrnInfoPtr pScrn, Bool canGrow);
+
+extern _X_EXPORT void
+xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
+
+extern _X_EXPORT Bool
+xf86SaveScreen(ScreenPtr pScreen, int mode);
+
+extern _X_EXPORT void
+xf86DisableUnusedFunctions(ScrnInfoPtr pScrn);
+
+extern _X_EXPORT DisplayModePtr
+xf86OutputFindClosestMode (xf86OutputPtr output, DisplayModePtr desired);
+
+extern _X_EXPORT Bool
+xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation);
+
+/**
+ * Set the EDID information for the specified output
+ */
+extern _X_EXPORT void
+xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon);
+
+/**
+ * Return the list of modes supported by the EDID information
+ * stored in 'output'
+ */
+extern _X_EXPORT DisplayModePtr
+xf86OutputGetEDIDModes (xf86OutputPtr output);
+
+extern _X_EXPORT xf86MonPtr
+xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus);
+
+/**
+ * Initialize dga for this screen
+ */
+
+#ifdef XFreeXDGA
+extern _X_EXPORT Bool
+xf86DiDGAInit (ScreenPtr pScreen, unsigned long dga_address);
+
+/* this is the real function, used only internally */
+_X_INTERNAL Bool
+_xf86_di_dga_init_internal (ScreenPtr pScreen);
+
+/**
+ * Re-initialize dga for this screen (as when the set of modes changes)
+ */
+
+extern _X_EXPORT Bool
+xf86DiDGAReInit (ScreenPtr pScreen);
+#endif
+
+/* This is the real function, used only internally */
+_X_INTERNAL Bool
+_xf86_di_dga_reinit_internal (ScreenPtr pScreen);
+
+/*
+ * Set the subpixel order reported for the screen using
+ * the information from the outputs
+ */
+
+extern _X_EXPORT void
+xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen);
+
+/*
+ * Get a standard string name for a connector type
+ */
+extern _X_EXPORT char *
+xf86ConnectorGetName(xf86ConnectorType connector);
+
+/*
+ * Using the desired mode information in each crtc, set
+ * modes (used in EnterVT functions, or at server startup)
+ */
+
+extern _X_EXPORT Bool
+xf86SetDesiredModes (ScrnInfoPtr pScrn);
+
+/**
+ * Initialize the CRTC-based cursor code. CRTC function vectors must
+ * contain relevant cursor setting functions.
+ *
+ * Driver should call this from ScreenInit function
+ */
+extern _X_EXPORT Bool
+xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags);
+
+/**
+ * Called when anything on the screen is reconfigured.
+ *
+ * Reloads cursor images as needed, then adjusts cursor positions.
+ *
+ * Driver should call this from crtc commit function.
+ */
+extern _X_EXPORT void
+xf86_reload_cursors (ScreenPtr screen);
+
+/**
+ * Called from EnterVT to turn the cursors back on
+ */
+extern _X_EXPORT void
+xf86_show_cursors (ScrnInfoPtr scrn);
+
+/**
+ * Called by the driver to turn cursors off
+ */
+extern _X_EXPORT void
+xf86_hide_cursors (ScrnInfoPtr scrn);
+
+/**
+ * Clean up CRTC-based cursor code. Driver must call this at CloseScreen time.
+ */
+extern _X_EXPORT void
+xf86_cursors_fini (ScreenPtr screen);
+
+/*
+ * For overlay video, compute the relevant CRTC and
+ * clip video to that.
+ * wraps xf86XVClipVideoHelper()
+ */
+
+extern _X_EXPORT Bool
+xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn,
+ xf86CrtcPtr *crtc_ret,
+ xf86CrtcPtr desired_crtc,
+ BoxPtr dst,
+ INT32 *xa,
+ INT32 *xb,
+ INT32 *ya,
+ INT32 *yb,
+ RegionPtr reg,
+ INT32 width,
+ INT32 height);
+
+extern _X_EXPORT xf86_crtc_notify_proc_ptr
+xf86_wrap_crtc_notify (ScreenPtr pScreen, xf86_crtc_notify_proc_ptr new);
+
+extern _X_EXPORT void
+xf86_unwrap_crtc_notify(ScreenPtr pScreen, xf86_crtc_notify_proc_ptr old);
+
+extern _X_EXPORT void
+xf86_crtc_notify(ScreenPtr pScreen);
+
+/**
+ * Gamma
+ */
+
+extern _X_EXPORT Bool
+xf86_crtc_supports_gamma(ScrnInfoPtr pScrn);
+
+#endif /* _XF86CRTC_H_ */
diff --git a/xorg-server/hw/xfree86/modes/xf86Cursors.c b/xorg-server/hw/xfree86/modes/xf86Cursors.c
index 066744744..5562f29cc 100644
--- a/xorg-server/hw/xfree86/modes/xf86Cursors.c
+++ b/xorg-server/hw/xfree86/modes/xf86Cursors.c
@@ -1,688 +1,688 @@
-/*
- * Copyright © 2007 Keith Packard
- * Copyright © 2010 Aaron Plattner
- *
- * 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 the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The 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 COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE 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.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#else
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#endif
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include "xf86Crtc.h"
-#include "xf86Modes.h"
-#include "xf86RandR12.h"
-#include "xf86CursorPriv.h"
-#include "X11/extensions/render.h"
-#include "X11/extensions/dpmsconst.h"
-#include "X11/Xatom.h"
-#include "picturestr.h"
-#include "cursorstr.h"
-#include "inputstr.h"
-
-/*
- * Given a screen coordinate, rotate back to a cursor source coordinate
- */
-static void
-xf86_crtc_rotate_coord (Rotation rotation,
- int width,
- int height,
- int x_dst,
- int y_dst,
- int *x_src,
- int *y_src)
-{
- int t;
-
- switch (rotation & 0xf) {
- case RR_Rotate_0:
- break;
- case RR_Rotate_90:
- t = x_dst;
- x_dst = height - y_dst - 1;
- y_dst = t;
- break;
- case RR_Rotate_180:
- x_dst = width - x_dst - 1;
- y_dst = height - y_dst - 1;
- break;
- case RR_Rotate_270:
- t = x_dst;
- x_dst = y_dst;
- y_dst = width - t - 1;
- break;
- }
- if (rotation & RR_Reflect_X)
- x_dst = width - x_dst - 1;
- if (rotation & RR_Reflect_Y)
- y_dst = height - y_dst - 1;
- *x_src = x_dst;
- *y_src = y_dst;
-}
-
-/*
- * Given a cursor source coordinate, rotate to a screen coordinate
- */
-static void
-xf86_crtc_rotate_coord_back (Rotation rotation,
- int width,
- int height,
- int x_dst,
- int y_dst,
- int *x_src,
- int *y_src)
-{
- int t;
-
- if (rotation & RR_Reflect_X)
- x_dst = width - x_dst - 1;
- if (rotation & RR_Reflect_Y)
- y_dst = height - y_dst - 1;
-
- switch (rotation & 0xf) {
- case RR_Rotate_0:
- break;
- case RR_Rotate_90:
- t = x_dst;
- x_dst = y_dst;
- y_dst = width - t - 1;
- break;
- case RR_Rotate_180:
- x_dst = width - x_dst - 1;
- y_dst = height - y_dst - 1;
- break;
- case RR_Rotate_270:
- t = x_dst;
- x_dst = height - y_dst - 1;
- y_dst = t;
- break;
- }
- *x_src = x_dst;
- *y_src = y_dst;
-}
-
-struct cursor_bit {
- CARD8 *byte;
- char bitpos;
-};
-
-/*
- * Convert an x coordinate to a position within the cursor bitmap
- */
-static struct cursor_bit
-cursor_bitpos (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y,
- Bool mask)
-{
- const int flags = cursor_info->Flags;
- const Bool interleaved =
- !!(flags & (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
- HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 |
- HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 |
- HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
- HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64));
- const int width = cursor_info->MaxWidth;
- const int height = cursor_info->MaxHeight;
- const int stride = interleaved ? width / 4 : width / 8;
-
- struct cursor_bit ret;
-
- image += y * stride;
-
- if (flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK)
- mask = !mask;
- if (flags & HARDWARE_CURSOR_NIBBLE_SWAPPED)
- x = (x & ~3) | (3 - (x & 3));
- if (((flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) == 0) ==
- (X_BYTE_ORDER == X_BIG_ENDIAN))
- x = (x & ~7) | (7 - (x & 7));
- if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1)
- x = (x << 1) + mask;
- else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8)
- x = ((x & ~7) << 1) | (mask << 3) | (x & 7);
- else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16)
- x = ((x & ~15) << 1) | (mask << 4) | (x & 15);
- else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32)
- x = ((x & ~31) << 1) | (mask << 5) | (x & 31);
- else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64)
- x = ((x & ~63) << 1) | (mask << 6) | (x & 63);
- else if (mask)
- image += stride * height;
-
- ret.byte = image + (x / 8);
- ret.bitpos = x & 7;
-
- return ret;
-}
-
-/*
- * Fetch one bit from a cursor bitmap
- */
-static CARD8
-get_bit (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask)
-{
- struct cursor_bit bit = cursor_bitpos(image, cursor_info, x, y, mask);
- return (*bit.byte >> bit.bitpos) & 1;
-}
-
-/*
- * Set one bit in a cursor bitmap
- */
-static void
-set_bit (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask)
-{
- struct cursor_bit bit = cursor_bitpos(image, cursor_info, x, y, mask);
- *bit.byte |= 1 << bit.bitpos;
-}
-
-/*
- * Load a two color cursor into a driver that supports only ARGB cursors
- */
-static void
-xf86_crtc_convert_cursor_to_argb (xf86CrtcPtr crtc, unsigned char *src)
-{
- ScrnInfoPtr scrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
- CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image;
- int x, y;
- int xin, yin;
- int flags = cursor_info->Flags;
- CARD32 bits;
-
-#ifdef ARGB_CURSOR
- crtc->cursor_argb = FALSE;
-#endif
-
- for (y = 0; y < cursor_info->MaxHeight; y++)
- for (x = 0; x < cursor_info->MaxWidth; x++)
- {
- xf86_crtc_rotate_coord (crtc->rotation,
- cursor_info->MaxWidth,
- cursor_info->MaxHeight,
- x, y, &xin, &yin);
- if (get_bit (src, cursor_info, xin, yin, TRUE) ==
- ((flags & HARDWARE_CURSOR_INVERT_MASK) == 0))
- {
- if (get_bit (src, cursor_info, xin, yin, FALSE))
- bits = xf86_config->cursor_fg;
- else
- bits = xf86_config->cursor_bg;
- }
- else
- bits = 0;
- cursor_image[y * cursor_info->MaxWidth + x] = bits;
- }
- crtc->funcs->load_cursor_argb (crtc, cursor_image);
-}
-
-/*
- * Set the colors for a two-color cursor (ignore for ARGB cursors)
- */
-static void
-xf86_set_cursor_colors (ScrnInfoPtr scrn, int bg, int fg)
-{
- ScreenPtr screen = scrn->pScreen;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- CursorPtr cursor = xf86_config->cursor;
- int c;
- CARD8 *bits = cursor ?
- dixLookupPrivate(&cursor->devPrivates, CursorScreenKey(screen))
- : NULL;
-
- /* Save ARGB versions of these colors */
- xf86_config->cursor_fg = (CARD32) fg | 0xff000000;
- xf86_config->cursor_bg = (CARD32) bg | 0xff000000;
-
- for (c = 0; c < xf86_config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = xf86_config->crtc[c];
-
- if (crtc->enabled && !crtc->cursor_argb)
- {
- if (crtc->funcs->load_cursor_image)
- crtc->funcs->set_cursor_colors (crtc, bg, fg);
- else if (bits)
- xf86_crtc_convert_cursor_to_argb (crtc, bits);
- }
- }
-}
-
-static void
-xf86_crtc_hide_cursor (xf86CrtcPtr crtc)
-{
- if (crtc->cursor_shown)
- {
- crtc->funcs->hide_cursor (crtc);
- crtc->cursor_shown = FALSE;
- }
-}
-
-void
-xf86_hide_cursors (ScrnInfoPtr scrn)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- int c;
-
- xf86_config->cursor_on = FALSE;
- for (c = 0; c < xf86_config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = xf86_config->crtc[c];
-
- if (crtc->enabled)
- xf86_crtc_hide_cursor (crtc);
- }
-}
-
-static void
-xf86_crtc_show_cursor (xf86CrtcPtr crtc)
-{
- if (!crtc->cursor_shown && crtc->cursor_in_range)
- {
- crtc->funcs->show_cursor (crtc);
- crtc->cursor_shown = TRUE;
- }
-}
-
-void
-xf86_show_cursors (ScrnInfoPtr scrn)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- int c;
-
- xf86_config->cursor_on = TRUE;
- for (c = 0; c < xf86_config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = xf86_config->crtc[c];
-
- if (crtc->enabled)
- xf86_crtc_show_cursor (crtc);
- }
-}
-
-static void
-xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
-{
- ScrnInfoPtr scrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
- DisplayModePtr mode = &crtc->mode;
- Bool in_range;
- int dx, dy;
-
- /*
- * Transform position of cursor on screen
- */
- if (crtc->transform_in_use)
- {
- ScreenPtr screen = scrn->pScreen;
- xf86CursorScreenPtr ScreenPriv =
- (xf86CursorScreenPtr)dixLookupPrivate(&screen->devPrivates,
- xf86CursorScreenKey);
- struct pict_f_vector v;
-
- v.v[0] = (x + ScreenPriv->HotX) + 0.5;
- v.v[1] = (y + ScreenPriv->HotY) + 0.5;
- v.v[2] = 1;
- pixman_f_transform_point (&crtc->f_framebuffer_to_crtc, &v);
- /* cursor will have 0.5 added to it already so floor is sufficent */
- x = floor (v.v[0]);
- y = floor (v.v[1]);
- /*
- * Transform position of cursor upper left corner
- */
- xf86_crtc_rotate_coord_back (crtc->rotation,
- cursor_info->MaxWidth,
- cursor_info->MaxHeight,
- ScreenPriv->HotX, ScreenPriv->HotY, &dx, &dy);
- x -= dx;
- y -= dy;
- }
- else
- {
- x -= crtc->x;
- y -= crtc->y;
- }
-
- /*
- * Disable the cursor when it is outside the viewport
- */
- in_range = TRUE;
- if (x >= mode->HDisplay || y >= mode->VDisplay ||
- x <= -cursor_info->MaxWidth || y <= -cursor_info->MaxHeight)
- {
- in_range = FALSE;
- x = 0;
- y = 0;
- }
-
- crtc->cursor_in_range = in_range;
-
- if (in_range)
- {
- crtc->funcs->set_cursor_position (crtc, x, y);
- xf86_crtc_show_cursor (crtc);
- }
- else
- xf86_crtc_hide_cursor (crtc);
-}
-
-static void
-xf86_set_cursor_position (ScrnInfoPtr scrn, int x, int y)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- int c;
-
- /* undo what xf86HWCurs did to the coordinates */
- x += scrn->frameX0;
- y += scrn->frameY0;
- for (c = 0; c < xf86_config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = xf86_config->crtc[c];
-
- if (crtc->enabled)
- xf86_crtc_set_cursor_position (crtc, x, y);
- }
-}
-
-/*
- * Load a two-color cursor into a crtc, performing rotation as needed
- */
-static void
-xf86_crtc_load_cursor_image (xf86CrtcPtr crtc, CARD8 *src)
-{
- ScrnInfoPtr scrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
- CARD8 *cursor_image;
-
-#ifdef ARGB_CURSOR
- crtc->cursor_argb = FALSE;
-#endif
-
- if (crtc->rotation == RR_Rotate_0)
- cursor_image = src;
- else
- {
- int x, y;
- int xin, yin;
- int stride = cursor_info->MaxWidth >> 2;
-
- cursor_image = xf86_config->cursor_image;
- memset(cursor_image, 0, cursor_info->MaxHeight * stride);
-
- for (y = 0; y < cursor_info->MaxHeight; y++)
- for (x = 0; x < cursor_info->MaxWidth; x++)
- {
- xf86_crtc_rotate_coord (crtc->rotation,
- cursor_info->MaxWidth,
- cursor_info->MaxHeight,
- x, y, &xin, &yin);
- if (get_bit(src, cursor_info, xin, yin, FALSE))
- set_bit(cursor_image, cursor_info, x, y, FALSE);
- if (get_bit(src, cursor_info, xin, yin, TRUE))
- set_bit(cursor_image, cursor_info, x, y, TRUE);
- }
- }
- crtc->funcs->load_cursor_image (crtc, cursor_image);
-}
-
-/*
- * Load a cursor image into all active CRTCs
- */
-static void
-xf86_load_cursor_image (ScrnInfoPtr scrn, unsigned char *src)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- int c;
-
- for (c = 0; c < xf86_config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = xf86_config->crtc[c];
-
- if (crtc->enabled)
- {
- if (crtc->funcs->load_cursor_image)
- xf86_crtc_load_cursor_image (crtc, src);
- else if (crtc->funcs->load_cursor_argb)
- xf86_crtc_convert_cursor_to_argb (crtc, src);
- }
- }
-}
-
-static Bool
-xf86_use_hw_cursor (ScreenPtr screen, CursorPtr cursor)
-{
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
-
- ++cursor->refcnt;
- if (xf86_config->cursor)
- FreeCursor (xf86_config->cursor, None);
- xf86_config->cursor = cursor;
-
- if (cursor->bits->width > cursor_info->MaxWidth ||
- cursor->bits->height> cursor_info->MaxHeight)
- return FALSE;
-
- return TRUE;
-}
-
-static Bool
-xf86_use_hw_cursor_argb (ScreenPtr screen, CursorPtr cursor)
-{
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
-
- ++cursor->refcnt;
- if (xf86_config->cursor)
- FreeCursor (xf86_config->cursor, None);
- xf86_config->cursor = cursor;
-
- /* Make sure ARGB support is available */
- if ((cursor_info->Flags & HARDWARE_CURSOR_ARGB) == 0)
- return FALSE;
-
- if (cursor->bits->width > cursor_info->MaxWidth ||
- cursor->bits->height> cursor_info->MaxHeight)
- return FALSE;
-
- return TRUE;
-}
-
-static void
-xf86_crtc_load_cursor_argb (xf86CrtcPtr crtc, CursorPtr cursor)
-{
- ScrnInfoPtr scrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
- CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image;
- CARD32 *cursor_source = (CARD32 *) cursor->bits->argb;
- int x, y;
- int xin, yin;
- CARD32 bits;
- int source_width = cursor->bits->width;
- int source_height = cursor->bits->height;
- int image_width = cursor_info->MaxWidth;
- int image_height = cursor_info->MaxHeight;
-
- for (y = 0; y < image_height; y++)
- for (x = 0; x < image_width; x++)
- {
- xf86_crtc_rotate_coord (crtc->rotation, image_width, image_height,
- x, y, &xin, &yin);
- if (xin < source_width && yin < source_height)
- bits = cursor_source[yin * source_width + xin];
- else
- bits = 0;
- cursor_image[y * image_width + x] = bits;
- }
-
- crtc->funcs->load_cursor_argb (crtc, cursor_image);
-}
-
-static void
-xf86_load_cursor_argb (ScrnInfoPtr scrn, CursorPtr cursor)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- int c;
-
- for (c = 0; c < xf86_config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = xf86_config->crtc[c];
-
- if (crtc->enabled)
- xf86_crtc_load_cursor_argb (crtc, cursor);
- }
-}
-
-Bool
-xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags)
-{
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- xf86CursorInfoPtr cursor_info;
-
- cursor_info = xf86CreateCursorInfoRec();
- if (!cursor_info)
- return FALSE;
-
- xf86_config->cursor_image = malloc(max_width * max_height * 4);
-
- if (!xf86_config->cursor_image)
- {
- xf86DestroyCursorInfoRec (cursor_info);
- return FALSE;
- }
-
- xf86_config->cursor_info = cursor_info;
-
- cursor_info->MaxWidth = max_width;
- cursor_info->MaxHeight = max_height;
- cursor_info->Flags = flags;
-
- cursor_info->SetCursorColors = xf86_set_cursor_colors;
- cursor_info->SetCursorPosition = xf86_set_cursor_position;
- cursor_info->LoadCursorImage = xf86_load_cursor_image;
- cursor_info->HideCursor = xf86_hide_cursors;
- cursor_info->ShowCursor = xf86_show_cursors;
- cursor_info->UseHWCursor = xf86_use_hw_cursor;
-#ifdef ARGB_CURSOR
- if (flags & HARDWARE_CURSOR_ARGB)
- {
- cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb;
- cursor_info->LoadCursorARGB = xf86_load_cursor_argb;
- }
-#endif
-
- xf86_config->cursor = NULL;
- xf86_hide_cursors (scrn);
-
- return xf86InitCursor (screen, cursor_info);
-}
-
-/**
- * Called when anything on the screen is reconfigured.
- *
- * Reloads cursor images as needed, then adjusts cursor positions
- */
-
-void
-xf86_reload_cursors (ScreenPtr screen)
-{
- ScrnInfoPtr scrn;
- xf86CrtcConfigPtr xf86_config;
- xf86CursorInfoPtr cursor_info;
- CursorPtr cursor;
- int x, y;
- xf86CursorScreenPtr cursor_screen_priv;
-
- /* initial mode setting will not have set a screen yet.
- May be called before the devices are initialised.
- */
- if (!screen || !inputInfo.pointer)
- return;
- cursor_screen_priv = dixLookupPrivate(&screen->devPrivates,
- xf86CursorScreenKey);
- /* return if HW cursor is inactive, to avoid displaying two cursors */
- if (!cursor_screen_priv || !cursor_screen_priv->isUp)
- return;
-
- scrn = xf86Screens[screen->myNum];
- xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-
- /* make sure the cursor code has been initialized */
- cursor_info = xf86_config->cursor_info;
- if (!cursor_info)
- return;
-
- cursor = xf86_config->cursor;
- GetSpritePosition (inputInfo.pointer, &x, &y);
- if (!(cursor_info->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
- (*cursor_info->HideCursor)(scrn);
-
- if (cursor)
- {
- void *src = dixLookupPrivate(&cursor->devPrivates, CursorScreenKey(screen));
-#ifdef ARGB_CURSOR
- if (cursor->bits->argb && cursor_info->LoadCursorARGB)
- (*cursor_info->LoadCursorARGB) (scrn, cursor);
- else if (src)
-#endif
- (*cursor_info->LoadCursorImage)(scrn, src);
-
- x += scrn->frameX0 + cursor_screen_priv->HotX;
- y += scrn->frameY0 + cursor_screen_priv->HotY;
- (*cursor_info->SetCursorPosition)(scrn, x, y);
- }
-}
-
-/**
- * Clean up CRTC-based cursor code
- */
-void
-xf86_cursors_fini (ScreenPtr screen)
-{
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-
- if (xf86_config->cursor_info)
- {
- xf86DestroyCursorInfoRec (xf86_config->cursor_info);
- xf86_config->cursor_info = NULL;
- }
- free(xf86_config->cursor_image);
- xf86_config->cursor_image = NULL;
- if (xf86_config->cursor)
- {
- FreeCursor (xf86_config->cursor, None);
- xf86_config->cursor = NULL;
- }
-}
+/*
+ * Copyright © 2007 Keith Packard
+ * Copyright © 2010 Aaron Plattner
+ *
+ * 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 the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The 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 COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE 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.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#else
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "xf86.h"
+#include "xf86DDC.h"
+#include "xf86Crtc.h"
+#include "xf86Modes.h"
+#include "xf86RandR12.h"
+#include "xf86CursorPriv.h"
+#include "X11/extensions/render.h"
+#include "X11/extensions/dpmsconst.h"
+#include "X11/Xatom.h"
+#include "picturestr.h"
+#include "cursorstr.h"
+#include "inputstr.h"
+
+/*
+ * Given a screen coordinate, rotate back to a cursor source coordinate
+ */
+static void
+xf86_crtc_rotate_coord (Rotation rotation,
+ int width,
+ int height,
+ int x_dst,
+ int y_dst,
+ int *x_src,
+ int *y_src)
+{
+ int t;
+
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ break;
+ case RR_Rotate_90:
+ t = x_dst;
+ x_dst = height - y_dst - 1;
+ y_dst = t;
+ break;
+ case RR_Rotate_180:
+ x_dst = width - x_dst - 1;
+ y_dst = height - y_dst - 1;
+ break;
+ case RR_Rotate_270:
+ t = x_dst;
+ x_dst = y_dst;
+ y_dst = width - t - 1;
+ break;
+ }
+ if (rotation & RR_Reflect_X)
+ x_dst = width - x_dst - 1;
+ if (rotation & RR_Reflect_Y)
+ y_dst = height - y_dst - 1;
+ *x_src = x_dst;
+ *y_src = y_dst;
+}
+
+/*
+ * Given a cursor source coordinate, rotate to a screen coordinate
+ */
+static void
+xf86_crtc_rotate_coord_back (Rotation rotation,
+ int width,
+ int height,
+ int x_dst,
+ int y_dst,
+ int *x_src,
+ int *y_src)
+{
+ int t;
+
+ if (rotation & RR_Reflect_X)
+ x_dst = width - x_dst - 1;
+ if (rotation & RR_Reflect_Y)
+ y_dst = height - y_dst - 1;
+
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ break;
+ case RR_Rotate_90:
+ t = x_dst;
+ x_dst = y_dst;
+ y_dst = width - t - 1;
+ break;
+ case RR_Rotate_180:
+ x_dst = width - x_dst - 1;
+ y_dst = height - y_dst - 1;
+ break;
+ case RR_Rotate_270:
+ t = x_dst;
+ x_dst = height - y_dst - 1;
+ y_dst = t;
+ break;
+ }
+ *x_src = x_dst;
+ *y_src = y_dst;
+}
+
+struct cursor_bit {
+ CARD8 *byte;
+ char bitpos;
+};
+
+/*
+ * Convert an x coordinate to a position within the cursor bitmap
+ */
+static struct cursor_bit
+cursor_bitpos (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y,
+ Bool mask)
+{
+ const int flags = cursor_info->Flags;
+ const Bool interleaved =
+ !!(flags & (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64));
+ const int width = cursor_info->MaxWidth;
+ const int height = cursor_info->MaxHeight;
+ const int stride = interleaved ? width / 4 : width / 8;
+
+ struct cursor_bit ret;
+
+ image += y * stride;
+
+ if (flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK)
+ mask = !mask;
+ if (flags & HARDWARE_CURSOR_NIBBLE_SWAPPED)
+ x = (x & ~3) | (3 - (x & 3));
+ if (((flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) == 0) ==
+ (X_BYTE_ORDER == X_BIG_ENDIAN))
+ x = (x & ~7) | (7 - (x & 7));
+ if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1)
+ x = (x << 1) + mask;
+ else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8)
+ x = ((x & ~7) << 1) | (mask << 3) | (x & 7);
+ else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16)
+ x = ((x & ~15) << 1) | (mask << 4) | (x & 15);
+ else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32)
+ x = ((x & ~31) << 1) | (mask << 5) | (x & 31);
+ else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64)
+ x = ((x & ~63) << 1) | (mask << 6) | (x & 63);
+ else if (mask)
+ image += stride * height;
+
+ ret.byte = image + (x / 8);
+ ret.bitpos = x & 7;
+
+ return ret;
+}
+
+/*
+ * Fetch one bit from a cursor bitmap
+ */
+static CARD8
+get_bit (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask)
+{
+ struct cursor_bit bit = cursor_bitpos(image, cursor_info, x, y, mask);
+ return (*bit.byte >> bit.bitpos) & 1;
+}
+
+/*
+ * Set one bit in a cursor bitmap
+ */
+static void
+set_bit (CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask)
+{
+ struct cursor_bit bit = cursor_bitpos(image, cursor_info, x, y, mask);
+ *bit.byte |= 1 << bit.bitpos;
+}
+
+/*
+ * Load a two color cursor into a driver that supports only ARGB cursors
+ */
+static void
+xf86_crtc_convert_cursor_to_argb (xf86CrtcPtr crtc, unsigned char *src)
+{
+ ScrnInfoPtr scrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+ CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image;
+ int x, y;
+ int xin, yin;
+ int flags = cursor_info->Flags;
+ CARD32 bits;
+
+#ifdef ARGB_CURSOR
+ crtc->cursor_argb = FALSE;
+#endif
+
+ for (y = 0; y < cursor_info->MaxHeight; y++)
+ for (x = 0; x < cursor_info->MaxWidth; x++)
+ {
+ xf86_crtc_rotate_coord (crtc->rotation,
+ cursor_info->MaxWidth,
+ cursor_info->MaxHeight,
+ x, y, &xin, &yin);
+ if (get_bit (src, cursor_info, xin, yin, TRUE) ==
+ ((flags & HARDWARE_CURSOR_INVERT_MASK) == 0))
+ {
+ if (get_bit (src, cursor_info, xin, yin, FALSE))
+ bits = xf86_config->cursor_fg;
+ else
+ bits = xf86_config->cursor_bg;
+ }
+ else
+ bits = 0;
+ cursor_image[y * cursor_info->MaxWidth + x] = bits;
+ }
+ crtc->funcs->load_cursor_argb (crtc, cursor_image);
+}
+
+/*
+ * Set the colors for a two-color cursor (ignore for ARGB cursors)
+ */
+static void
+xf86_set_cursor_colors (ScrnInfoPtr scrn, int bg, int fg)
+{
+ ScreenPtr screen = scrn->pScreen;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ CursorPtr cursor = xf86_config->cursor;
+ int c;
+ CARD8 *bits = cursor ?
+ dixLookupPrivate(&cursor->devPrivates, CursorScreenKey(screen))
+ : NULL;
+
+ /* Save ARGB versions of these colors */
+ xf86_config->cursor_fg = (CARD32) fg | 0xff000000;
+ xf86_config->cursor_bg = (CARD32) bg | 0xff000000;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->enabled && !crtc->cursor_argb)
+ {
+ if (crtc->funcs->load_cursor_image)
+ crtc->funcs->set_cursor_colors (crtc, bg, fg);
+ else if (bits)
+ xf86_crtc_convert_cursor_to_argb (crtc, bits);
+ }
+ }
+}
+
+static void
+xf86_crtc_hide_cursor (xf86CrtcPtr crtc)
+{
+ if (crtc->cursor_shown)
+ {
+ crtc->funcs->hide_cursor (crtc);
+ crtc->cursor_shown = FALSE;
+ }
+}
+
+void
+xf86_hide_cursors (ScrnInfoPtr scrn)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ xf86_config->cursor_on = FALSE;
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->enabled)
+ xf86_crtc_hide_cursor (crtc);
+ }
+}
+
+static void
+xf86_crtc_show_cursor (xf86CrtcPtr crtc)
+{
+ if (!crtc->cursor_shown && crtc->cursor_in_range)
+ {
+ crtc->funcs->show_cursor (crtc);
+ crtc->cursor_shown = TRUE;
+ }
+}
+
+void
+xf86_show_cursors (ScrnInfoPtr scrn)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ xf86_config->cursor_on = TRUE;
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->enabled)
+ xf86_crtc_show_cursor (crtc);
+ }
+}
+
+static void
+xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+{
+ ScrnInfoPtr scrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+ DisplayModePtr mode = &crtc->mode;
+ Bool in_range;
+ int dx, dy;
+
+ /*
+ * Transform position of cursor on screen
+ */
+ if (crtc->transform_in_use)
+ {
+ ScreenPtr screen = scrn->pScreen;
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)dixLookupPrivate(&screen->devPrivates,
+ xf86CursorScreenKey);
+ struct pict_f_vector v;
+
+ v.v[0] = (x + ScreenPriv->HotX) + 0.5;
+ v.v[1] = (y + ScreenPriv->HotY) + 0.5;
+ v.v[2] = 1;
+ pixman_f_transform_point (&crtc->f_framebuffer_to_crtc, &v);
+ /* cursor will have 0.5 added to it already so floor is sufficent */
+ x = floor (v.v[0]);
+ y = floor (v.v[1]);
+ /*
+ * Transform position of cursor upper left corner
+ */
+ xf86_crtc_rotate_coord_back (crtc->rotation,
+ cursor_info->MaxWidth,
+ cursor_info->MaxHeight,
+ ScreenPriv->HotX, ScreenPriv->HotY, &dx, &dy);
+ x -= dx;
+ y -= dy;
+ }
+ else
+ {
+ x -= crtc->x;
+ y -= crtc->y;
+ }
+
+ /*
+ * Disable the cursor when it is outside the viewport
+ */
+ in_range = TRUE;
+ if (x >= mode->HDisplay || y >= mode->VDisplay ||
+ x <= -cursor_info->MaxWidth || y <= -cursor_info->MaxHeight)
+ {
+ in_range = FALSE;
+ x = 0;
+ y = 0;
+ }
+
+ crtc->cursor_in_range = in_range;
+
+ if (in_range)
+ {
+ crtc->funcs->set_cursor_position (crtc, x, y);
+ xf86_crtc_show_cursor (crtc);
+ }
+ else
+ xf86_crtc_hide_cursor (crtc);
+}
+
+static void
+xf86_set_cursor_position (ScrnInfoPtr scrn, int x, int y)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ /* undo what xf86HWCurs did to the coordinates */
+ x += scrn->frameX0;
+ y += scrn->frameY0;
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->enabled)
+ xf86_crtc_set_cursor_position (crtc, x, y);
+ }
+}
+
+/*
+ * Load a two-color cursor into a crtc, performing rotation as needed
+ */
+static void
+xf86_crtc_load_cursor_image (xf86CrtcPtr crtc, CARD8 *src)
+{
+ ScrnInfoPtr scrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+ CARD8 *cursor_image;
+
+#ifdef ARGB_CURSOR
+ crtc->cursor_argb = FALSE;
+#endif
+
+ if (crtc->rotation == RR_Rotate_0)
+ cursor_image = src;
+ else
+ {
+ int x, y;
+ int xin, yin;
+ int stride = cursor_info->MaxWidth >> 2;
+
+ cursor_image = xf86_config->cursor_image;
+ memset(cursor_image, 0, cursor_info->MaxHeight * stride);
+
+ for (y = 0; y < cursor_info->MaxHeight; y++)
+ for (x = 0; x < cursor_info->MaxWidth; x++)
+ {
+ xf86_crtc_rotate_coord (crtc->rotation,
+ cursor_info->MaxWidth,
+ cursor_info->MaxHeight,
+ x, y, &xin, &yin);
+ if (get_bit(src, cursor_info, xin, yin, FALSE))
+ set_bit(cursor_image, cursor_info, x, y, FALSE);
+ if (get_bit(src, cursor_info, xin, yin, TRUE))
+ set_bit(cursor_image, cursor_info, x, y, TRUE);
+ }
+ }
+ crtc->funcs->load_cursor_image (crtc, cursor_image);
+}
+
+/*
+ * Load a cursor image into all active CRTCs
+ */
+static void
+xf86_load_cursor_image (ScrnInfoPtr scrn, unsigned char *src)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->enabled)
+ {
+ if (crtc->funcs->load_cursor_image)
+ xf86_crtc_load_cursor_image (crtc, src);
+ else if (crtc->funcs->load_cursor_argb)
+ xf86_crtc_convert_cursor_to_argb (crtc, src);
+ }
+ }
+}
+
+static Bool
+xf86_use_hw_cursor (ScreenPtr screen, CursorPtr cursor)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+
+ ++cursor->refcnt;
+ if (xf86_config->cursor)
+ FreeCursor (xf86_config->cursor, None);
+ xf86_config->cursor = cursor;
+
+ if (cursor->bits->width > cursor_info->MaxWidth ||
+ cursor->bits->height> cursor_info->MaxHeight)
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+xf86_use_hw_cursor_argb (ScreenPtr screen, CursorPtr cursor)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+
+ ++cursor->refcnt;
+ if (xf86_config->cursor)
+ FreeCursor (xf86_config->cursor, None);
+ xf86_config->cursor = cursor;
+
+ /* Make sure ARGB support is available */
+ if ((cursor_info->Flags & HARDWARE_CURSOR_ARGB) == 0)
+ return FALSE;
+
+ if (cursor->bits->width > cursor_info->MaxWidth ||
+ cursor->bits->height> cursor_info->MaxHeight)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+xf86_crtc_load_cursor_argb (xf86CrtcPtr crtc, CursorPtr cursor)
+{
+ ScrnInfoPtr scrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+ CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image;
+ CARD32 *cursor_source = (CARD32 *) cursor->bits->argb;
+ int x, y;
+ int xin, yin;
+ CARD32 bits;
+ int source_width = cursor->bits->width;
+ int source_height = cursor->bits->height;
+ int image_width = cursor_info->MaxWidth;
+ int image_height = cursor_info->MaxHeight;
+
+ for (y = 0; y < image_height; y++)
+ for (x = 0; x < image_width; x++)
+ {
+ xf86_crtc_rotate_coord (crtc->rotation, image_width, image_height,
+ x, y, &xin, &yin);
+ if (xin < source_width && yin < source_height)
+ bits = cursor_source[yin * source_width + xin];
+ else
+ bits = 0;
+ cursor_image[y * image_width + x] = bits;
+ }
+
+ crtc->funcs->load_cursor_argb (crtc, cursor_image);
+}
+
+static void
+xf86_load_cursor_argb (ScrnInfoPtr scrn, CursorPtr cursor)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->enabled)
+ xf86_crtc_load_cursor_argb (crtc, cursor);
+ }
+}
+
+Bool
+xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info;
+
+ cursor_info = xf86CreateCursorInfoRec();
+ if (!cursor_info)
+ return FALSE;
+
+ xf86_config->cursor_image = malloc(max_width * max_height * 4);
+
+ if (!xf86_config->cursor_image)
+ {
+ xf86DestroyCursorInfoRec (cursor_info);
+ return FALSE;
+ }
+
+ xf86_config->cursor_info = cursor_info;
+
+ cursor_info->MaxWidth = max_width;
+ cursor_info->MaxHeight = max_height;
+ cursor_info->Flags = flags;
+
+ cursor_info->SetCursorColors = xf86_set_cursor_colors;
+ cursor_info->SetCursorPosition = xf86_set_cursor_position;
+ cursor_info->LoadCursorImage = xf86_load_cursor_image;
+ cursor_info->HideCursor = xf86_hide_cursors;
+ cursor_info->ShowCursor = xf86_show_cursors;
+ cursor_info->UseHWCursor = xf86_use_hw_cursor;
+#ifdef ARGB_CURSOR
+ if (flags & HARDWARE_CURSOR_ARGB)
+ {
+ cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb;
+ cursor_info->LoadCursorARGB = xf86_load_cursor_argb;
+ }
+#endif
+
+ xf86_config->cursor = NULL;
+ xf86_hide_cursors (scrn);
+
+ return xf86InitCursor (screen, cursor_info);
+}
+
+/**
+ * Called when anything on the screen is reconfigured.
+ *
+ * Reloads cursor images as needed, then adjusts cursor positions
+ */
+
+void
+xf86_reload_cursors (ScreenPtr screen)
+{
+ ScrnInfoPtr scrn;
+ xf86CrtcConfigPtr xf86_config;
+ xf86CursorInfoPtr cursor_info;
+ CursorPtr cursor;
+ int x, y;
+ xf86CursorScreenPtr cursor_screen_priv;
+
+ /* initial mode setting will not have set a screen yet.
+ May be called before the devices are initialised.
+ */
+ if (!screen || !inputInfo.pointer)
+ return;
+ cursor_screen_priv = dixLookupPrivate(&screen->devPrivates,
+ xf86CursorScreenKey);
+ /* return if HW cursor is inactive, to avoid displaying two cursors */
+ if (!cursor_screen_priv || !cursor_screen_priv->isUp)
+ return;
+
+ scrn = xf86Screens[screen->myNum];
+ xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ /* make sure the cursor code has been initialized */
+ cursor_info = xf86_config->cursor_info;
+ if (!cursor_info)
+ return;
+
+ cursor = xf86_config->cursor;
+ GetSpritePosition (inputInfo.pointer, &x, &y);
+ if (!(cursor_info->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
+ (*cursor_info->HideCursor)(scrn);
+
+ if (cursor)
+ {
+ void *src = dixLookupPrivate(&cursor->devPrivates, CursorScreenKey(screen));
+#ifdef ARGB_CURSOR
+ if (cursor->bits->argb && cursor_info->LoadCursorARGB)
+ (*cursor_info->LoadCursorARGB) (scrn, cursor);
+ else if (src)
+#endif
+ (*cursor_info->LoadCursorImage)(scrn, src);
+
+ x += scrn->frameX0 + cursor_screen_priv->HotX;
+ y += scrn->frameY0 + cursor_screen_priv->HotY;
+ (*cursor_info->SetCursorPosition)(scrn, x, y);
+ }
+}
+
+/**
+ * Clean up CRTC-based cursor code
+ */
+void
+xf86_cursors_fini (ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ if (xf86_config->cursor_info)
+ {
+ xf86DestroyCursorInfoRec (xf86_config->cursor_info);
+ xf86_config->cursor_info = NULL;
+ }
+ free(xf86_config->cursor_image);
+ xf86_config->cursor_image = NULL;
+ if (xf86_config->cursor)
+ {
+ FreeCursor (xf86_config->cursor, None);
+ xf86_config->cursor = NULL;
+ }
+}
diff --git a/xorg-server/hw/xfree86/modes/xf86RandR12.c b/xorg-server/hw/xfree86/modes/xf86RandR12.c
index cb20d1c35..6d676363b 100644
--- a/xorg-server/hw/xfree86/modes/xf86RandR12.c
+++ b/xorg-server/hw/xfree86/modes/xf86RandR12.c
@@ -1,1823 +1,1823 @@
-/*
- * Copyright © 2002 Keith Packard, member of 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 name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The 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 COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE 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.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#else
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#endif
-
-#include "xf86.h"
-#include "os.h"
-#include "globals.h"
-#include "xf86Priv.h"
-#include "xf86DDC.h"
-#include "mipointer.h"
-#include "windowstr.h"
-#include "inputstr.h"
-#include <randrstr.h>
-#include <X11/extensions/render.h>
-
-#include "xf86Crtc.h"
-#include "xf86RandR12.h"
-
-typedef struct _xf86RandR12Info {
- int virtualX;
- int virtualY;
- int mmWidth;
- int mmHeight;
- int maxX;
- int maxY;
- int pointerX;
- int pointerY;
- Rotation rotation; /* current mode */
- Rotation supported_rotations; /* driver supported */
-
- /* Used to wrap EnterVT so we can re-probe the outputs when a laptop unsuspends
- * (actually, any time that we switch back into our VT).
- *
- * See https://bugs.freedesktop.org/show_bug.cgi?id=21554
- */
- xf86EnterVTProc *orig_EnterVT;
-} XF86RandRInfoRec, *XF86RandRInfoPtr;
-
-#ifdef RANDR_12_INTERFACE
-static Bool xf86RandR12Init12 (ScreenPtr pScreen);
-static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen);
-#endif
-
-static int xf86RandR12Generation;
-
-static DevPrivateKeyRec xf86RandR12KeyRec;
-static DevPrivateKey xf86RandR12Key;
-#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \
- dixLookupPrivate(&(p)->devPrivates, xf86RandR12Key))
-
-
-static int
-xf86RandR12ModeRefresh (DisplayModePtr mode)
-{
- if (mode->VRefresh)
- return (int) (mode->VRefresh + 0.5);
- else
- return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
-}
-
-/* Adapt panning area; return TRUE if panning area was valid without adaption */
-static int
-xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeight)
-{
- int ret = TRUE;
-
- if (crtc->version < 2)
- return FALSE;
-
- if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1) {
- /* Panning in X is disabled */
- if (crtc->panningTotalArea.x1 || crtc->panningTotalArea.x2)
- /* Illegal configuration -> fail/disable */
- ret = FALSE;
- crtc->panningTotalArea.x1 = crtc->panningTotalArea.x2 = 0;
- crtc->panningTrackingArea.x1 = crtc->panningTrackingArea.x2 = 0;
- crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
- } else {
- /* Panning in X is enabled */
- if (crtc->panningTotalArea.x1 < 0) {
- /* Panning region outside screen -> move inside */
- crtc->panningTotalArea.x2 -= crtc->panningTotalArea.x1;
- crtc->panningTotalArea.x1 = 0;
- ret = FALSE;
- }
- if (crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay) {
- /* Panning region smaller than displayed area -> crop to displayed area */
- crtc->panningTotalArea.x2 = crtc->panningTotalArea.x1 + crtc->mode.HDisplay;
- ret = FALSE;
- }
- if (crtc->panningTotalArea.x2 > screenWidth) {
- /* Panning region larger than screen -> move inside, then crop to screen */
- crtc->panningTotalArea.x1 -= crtc->panningTotalArea.x2 - screenWidth;
- crtc->panningTotalArea.x2 = screenWidth;
- ret = FALSE;
- if (crtc->panningTotalArea.x1 < 0)
- crtc->panningTotalArea.x1 = 0;
- }
- if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay) {
- /* Borders too large -> set to 0 */
- crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
- ret = FALSE;
- }
- }
-
- if (crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) {
- /* Panning in Y is disabled */
- if (crtc->panningTotalArea.y1 || crtc->panningTotalArea.y2)
- /* Illegal configuration -> fail/disable */
- ret = FALSE;
- crtc->panningTotalArea.y1 = crtc->panningTotalArea.y2 = 0;
- crtc->panningTrackingArea.y1 = crtc->panningTrackingArea.y2 = 0;
- crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
- } else {
- /* Panning in Y is enabled */
- if (crtc->panningTotalArea.y1 < 0) {
- /* Panning region outside screen -> move inside */
- crtc->panningTotalArea.y2 -= crtc->panningTotalArea.y1;
- crtc->panningTotalArea.y1 = 0;
- ret = FALSE;
- }
- if (crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay) {
- /* Panning region smaller than displayed area -> crop to displayed area */
- crtc->panningTotalArea.y2 = crtc->panningTotalArea.y1 + crtc->mode.VDisplay;
- ret = FALSE;
- }
- if (crtc->panningTotalArea.y2 > screenHeight) {
- /* Panning region larger than screen -> move inside, then crop to screen */
- crtc->panningTotalArea.y1 -= crtc->panningTotalArea.y2 - screenHeight;
- crtc->panningTotalArea.y2 = screenHeight;
- ret = FALSE;
- if (crtc->panningTotalArea.y1 < 0)
- crtc->panningTotalArea.y1 = 0;
- }
- if (crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) {
- /* Borders too large -> set to 0 */
- crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
- ret = FALSE;
- }
- }
-
- return ret;
-}
-
-/*
- * The heart of the panning operation:
- *
- * Given a frame buffer position (fb_x, fb_y),
- * and a crtc position (crtc_x, crtc_y),
- * and a transform matrix which maps frame buffer to crtc,
- * compute a panning position (pan_x, pan_y) that
- * makes the resulting transform line those two up
- */
-
-static void
-xf86ComputeCrtcPan (Bool transform_in_use,
- struct pixman_f_transform *m,
- double screen_x, double screen_y,
- double crtc_x, double crtc_y,
- int old_pan_x, int old_pan_y,
- int *new_pan_x, int *new_pan_y)
-{
- if (transform_in_use) {
- /*
- * Given the current transform, M, the current position
- * on the Screen, S, and the desired position on the CRTC,
- * C, compute a translation, T, such that:
- *
- * M T S = C
- *
- * where T is of the form
- *
- * | 1 0 dx |
- * | 0 1 dy |
- * | 0 0 1 |
- *
- * M T S =
- * | M00 Sx + M01 Sy + M00 dx + M01 dy + M02 | | Cx F |
- * | M10 Sx + M11 Sy + M10 dx + M11 dy + M12 | = | Cy F |
- * | M20 Sx + M21 Sy + M20 dx + M21 dy + M22 | | F |
- *
- * R = M S
- *
- * Cx F = M00 dx + M01 dy + R0
- * Cy F = M10 dx + M11 dy + R1
- * F = M20 dx + M21 dy + R2
- *
- * Zero out dx, then dy
- *
- * F (Cx M10 - Cy M00) =
- * (M10 M01 - M00 M11) dy + M10 R0 - M00 R1
- * F (M10 - Cy M20) =
- * (M10 M21 - M20 M11) dy + M10 R2 - M20 R1
- *
- * F (Cx M11 - Cy M01) =
- * (M11 M00 - M01 M10) dx + M11 R0 - M01 R1
- * F (M11 - Cy M21) =
- * (M11 M20 - M21 M10) dx + M11 R2 - M21 R1
- *
- * Make some temporaries
- *
- * T = | Cx M10 - Cy M00 |
- * | Cx M11 - Cy M01 |
- *
- * U = | M10 M01 - M00 M11 |
- * | M11 M00 - M01 M10 |
- *
- * Q = | M10 R0 - M00 R1 |
- * | M11 R0 - M01 R1 |
- *
- * P = | M10 - Cy M20 |
- * | M11 - Cy M21 |
- *
- * W = | M10 M21 - M20 M11 |
- * | M11 M20 - M21 M10 |
- *
- * V = | M10 R2 - M20 R1 |
- * | M11 R2 - M21 R1 |
- *
- * Rewrite:
- *
- * F T0 = U0 dy + Q0
- * F P0 = W0 dy + V0
- * F T1 = U1 dx + Q1
- * F P1 = W1 dx + V1
- *
- * Solve for F (two ways)
- *
- * F (W0 T0 - U0 P0) = W0 Q0 - U0 V0
- *
- * W0 Q0 - U0 V0
- * F = -------------
- * W0 T0 - U0 P0
- *
- * F (W1 T1 - U1 P1) = W1 Q1 - U1 V1
- *
- * W1 Q1 - U1 V1
- * F = -------------
- * W1 T1 - U1 P1
- *
- * We'll use which ever solution works (denominator != 0)
- *
- * Finally, solve for dx and dy:
- *
- * dx = (F T1 - Q1) / U1
- * dx = (F P1 - V1) / W1
- *
- * dy = (F T0 - Q0) / U0
- * dy = (F P0 - V0) / W0
- */
- double r[3];
- double q[2], u[2], t[2], v[2], w[2], p[2];
- double f;
- struct pict_f_vector d;
- int i;
-
- /* Get the un-normalized crtc coordinates again */
- for (i = 0; i < 3; i++)
- r[i] = m->m[i][0] * screen_x + m->m[i][1] * screen_y + m->m[i][2];
-
- /* Combine values into temporaries */
- for (i = 0; i < 2; i++) {
- q[i] = m->m[1][i] * r[0] - m->m[0][i] * r[1];
- u[i] = m->m[1][i] * m->m[0][1-i] - m->m[0][i] * m->m[1][1-i];
- t[i] = m->m[1][i] * crtc_x - m->m[0][i] * crtc_y;
-
- v[i] = m->m[1][i] * r[2] - m->m[2][i] * r[1];
- w[i] = m->m[1][i] * m->m[2][1-i] - m->m[2][i] * m->m[1][1-i];
- p[i] = m->m[1][i] - m->m[2][i] * crtc_y;
- }
-
- /* Find a way to compute f */
- f = 0;
- for (i = 0; i < 2; i++) {
- double a = w[i] * q[i] - u[i] * v[i];
- double b = w[i] * t[i] - u[i] * p[i];
- if (b != 0) {
- f = a/b;
- break;
- }
- }
-
- /* Solve for the resulting transform vector */
- for (i = 0; i < 2; i++) {
- if (u[i])
- d.v[1-i] = (t[i] * f - q[i]) / u[i];
- else if (w[1])
- d.v[1-i] = (p[i] * f - v[i]) / w[i];
- else
- d.v[1-i] = 0;
- }
- *new_pan_x = old_pan_x - floor (d.v[0] + 0.5);
- *new_pan_y = old_pan_y - floor (d.v[1] + 0.5);
- } else {
- *new_pan_x = screen_x - crtc_x;
- *new_pan_y = screen_y - crtc_y;
- }
-}
-
-static void
-xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
-{
- int newX, newY;
- int width, height;
- Bool panned = FALSE;
-
- if (crtc->version < 2)
- return;
-
- if (! crtc->enabled ||
- (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 &&
- crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1))
- return;
-
- newX = crtc->x;
- newY = crtc->y;
- width = crtc->mode.HDisplay;
- height = crtc->mode.VDisplay;
-
- if ((crtc->panningTrackingArea.x2 <= crtc->panningTrackingArea.x1 ||
- (x >= crtc->panningTrackingArea.x1 && x < crtc->panningTrackingArea.x2)) &&
- (crtc->panningTrackingArea.y2 <= crtc->panningTrackingArea.y1 ||
- (y >= crtc->panningTrackingArea.y1 && y < crtc->panningTrackingArea.y2)))
- {
- struct pict_f_vector c;
-
- /*
- * Pre-clip the mouse position to the panning area so that we don't
- * push the crtc outside. This doesn't deal with changes to the
- * panning values, only mouse position changes.
- */
- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1)
- {
- if (x < crtc->panningTotalArea.x1)
- x = crtc->panningTotalArea.x1;
- if (x >= crtc->panningTotalArea.x2)
- x = crtc->panningTotalArea.x2 - 1;
- }
- if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1)
- {
- if (y < crtc->panningTotalArea.y1)
- y = crtc->panningTotalArea.y1;
- if (y >= crtc->panningTotalArea.y2)
- y = crtc->panningTotalArea.y2 - 1;
- }
-
- c.v[0] = x;
- c.v[1] = y;
- c.v[2] = 1.0;
- if (crtc->transform_in_use) {
- pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &c);
- } else {
- c.v[0] -= crtc->x;
- c.v[1] -= crtc->y;
- }
-
- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
- if (c.v[0] < crtc->panningBorder[0]) {
- c.v[0] = crtc->panningBorder[0];
- panned = TRUE;
- }
- if (c.v[0] >= width - crtc->panningBorder[2]) {
- c.v[0] = width - crtc->panningBorder[2] - 1;
- panned = TRUE;
- }
- }
- if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
- if (c.v[1] < crtc->panningBorder[1]) {
- c.v[1] = crtc->panningBorder[1];
- panned = TRUE;
- }
- if (c.v[1] >= height - crtc->panningBorder[3]) {
- c.v[1] = height - crtc->panningBorder[3] - 1;
- panned = TRUE;
- }
- }
- if (panned)
- xf86ComputeCrtcPan (crtc->transform_in_use,
- &crtc->f_framebuffer_to_crtc,
- x, y, c.v[0], c.v[1],
- newX, newY, &newX, &newY);
- }
-
- /*
- * Ensure that the crtc is within the panning region.
- *
- * XXX This computation only works when we do not have a transform
- * in use.
- */
- if (!crtc->transform_in_use)
- {
- /* Validate against [xy]1 after [xy]2, to be sure that results are > 0 for [xy]1 > 0 */
- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
- if (newX > crtc->panningTotalArea.x2 - width)
- newX = crtc->panningTotalArea.x2 - width;
- if (newX < crtc->panningTotalArea.x1)
- newX = crtc->panningTotalArea.x1;
- }
- if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
- if (newY > crtc->panningTotalArea.y2 - height)
- newY = crtc->panningTotalArea.y2 - height;
- if (newY < crtc->panningTotalArea.y1)
- newY = crtc->panningTotalArea.y1;
- }
- }
- if (newX != crtc->x || newY != crtc->y)
- xf86CrtcSetOrigin (crtc, newX, newY);
-}
-
-static Bool
-xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
-{
- RRScreenSizePtr pSize;
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- DisplayModePtr mode;
- int refresh0 = 60;
- int maxX = 0, maxY = 0;
-
- *rotations = randrp->supported_rotations;
-
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = scrp->virtualX;
- randrp->virtualY = scrp->virtualY;
- }
-
- /* Re-probe the outputs for new monitors or modes */
- if (scrp->vtSema)
- {
- xf86ProbeOutputModes (scrp, 0, 0);
- xf86SetScrnInfoModes (scrp);
- }
-
- for (mode = scrp->modes; ; mode = mode->next)
- {
- int refresh = xf86RandR12ModeRefresh (mode);
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- if (maxX < mode->HDisplay)
- maxX = mode->HDisplay;
- if (maxY < mode->VDisplay)
- maxY = mode->VDisplay;
- }
- if (mode == scrp->modes)
- refresh0 = refresh;
- pSize = RRRegisterSize (pScreen,
- mode->HDisplay, mode->VDisplay,
- randrp->mmWidth, randrp->mmHeight);
- if (!pSize)
- return FALSE;
- RRRegisterRate (pScreen, pSize, refresh);
-
- if (xf86ModesEqual(mode, scrp->currentMode))
- {
- RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
- }
- if (mode->next == scrp->modes)
- break;
- }
-
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- randrp->maxX = maxX;
- randrp->maxY = maxY;
- }
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12SetMode (ScreenPtr pScreen,
- DisplayModePtr mode,
- Bool useVirtual,
- int mmWidth,
- int mmHeight)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- int oldWidth = pScreen->width;
- int oldHeight = pScreen->height;
- int oldmmWidth = pScreen->mmWidth;
- int oldmmHeight = pScreen->mmHeight;
- WindowPtr pRoot = pScreen->root;
- DisplayModePtr currentMode = NULL;
- Bool ret = TRUE;
-
- if (pRoot)
- (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
- if (useVirtual)
- {
- scrp->virtualX = randrp->virtualX;
- scrp->virtualY = randrp->virtualY;
- }
- else
- {
- scrp->virtualX = mode->HDisplay;
- scrp->virtualY = mode->VDisplay;
- }
-
- if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
- {
- /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
- pScreen->width = scrp->virtualY;
- pScreen->height = scrp->virtualX;
- pScreen->mmWidth = mmHeight;
- pScreen->mmHeight = mmWidth;
- }
- else
- {
- pScreen->width = scrp->virtualX;
- pScreen->height = scrp->virtualY;
- pScreen->mmWidth = mmWidth;
- pScreen->mmHeight = mmHeight;
- }
- if (scrp->currentMode == mode) {
- /* Save current mode */
- currentMode = scrp->currentMode;
- /* Reset, just so we ensure the drivers SwitchMode is called */
- scrp->currentMode = NULL;
- }
- /*
- * We know that if the driver failed to SwitchMode to the rotated
- * version, then it should revert back to it's prior mode.
- */
- if (!xf86SwitchMode (pScreen, mode))
- {
- ret = FALSE;
- scrp->virtualX = pScreen->width = oldWidth;
- scrp->virtualY = pScreen->height = oldHeight;
- pScreen->mmWidth = oldmmWidth;
- pScreen->mmHeight = oldmmHeight;
- scrp->currentMode = currentMode;
- }
-
- /*
- * Make sure the layout is correct
- */
- xf86ReconfigureLayout();
-
- /*
- * Make sure the whole screen is visible
- */
- xf86SetViewport (pScreen, pScreen->width, pScreen->height);
- xf86SetViewport (pScreen, 0, 0);
- if (pRoot)
- (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
- return ret;
-}
-
-Bool
-xf86RandR12SetConfig (ScreenPtr pScreen,
- Rotation rotation,
- int rate,
- RRScreenSizePtr pSize)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- DisplayModePtr mode;
- int pos[MAXDEVICES][2];
- Bool useVirtual = FALSE;
- int maxX = 0, maxY = 0;
- Rotation oldRotation = randrp->rotation;
- DeviceIntPtr dev;
- Bool view_adjusted = FALSE;
-
- randrp->rotation = rotation;
-
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = scrp->virtualX;
- randrp->virtualY = scrp->virtualY;
- }
-
- for (dev = inputInfo.devices; dev; dev = dev->next)
- {
- if (!IsMaster(dev) && !IsFloating(dev))
- continue;
-
- miPointerGetPosition(dev, &pos[dev->id][0], &pos[dev->id][1]);
- }
-
- for (mode = scrp->modes; ; mode = mode->next)
- {
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- if (maxX < mode->HDisplay)
- maxX = mode->HDisplay;
- if (maxY < mode->VDisplay)
- maxY = mode->VDisplay;
- }
- if (mode->HDisplay == pSize->width &&
- mode->VDisplay == pSize->height &&
- (rate == 0 || xf86RandR12ModeRefresh (mode) == rate))
- break;
- if (mode->next == scrp->modes)
- {
- if (pSize->width == randrp->virtualX &&
- pSize->height == randrp->virtualY)
- {
- mode = scrp->modes;
- useVirtual = TRUE;
- break;
- }
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- randrp->maxX = maxX;
- randrp->maxY = maxY;
- }
- return FALSE;
- }
- }
-
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- randrp->maxX = maxX;
- randrp->maxY = maxY;
- }
-
- if (!xf86RandR12SetMode (pScreen, mode, useVirtual, pSize->mmWidth,
- pSize->mmHeight)) {
- randrp->rotation = oldRotation;
- return FALSE;
- }
-
- /*
- * Move the cursor back where it belongs; SwitchMode repositions it
- * FIXME: duplicated code, see modes/xf86RandR12.c
- */
- for (dev = inputInfo.devices; dev; dev = dev->next)
- {
- if (!IsMaster(dev) && !IsFloating(dev))
- continue;
-
- if (pScreen == miPointerGetScreen(dev)) {
- int px = pos[dev->id][0];
- int py = pos[dev->id][1];
-
- px = (px >= pScreen->width ? (pScreen->width - 1) : px);
- py = (py >= pScreen->height ? (pScreen->height - 1) : py);
-
- /* Setting the viewpoint makes only sense on one device */
- if (!view_adjusted && IsMaster(dev)) {
- xf86SetViewport(pScreen, px, py);
- view_adjusted = TRUE;
- }
-
- (*pScreen->SetCursorPosition) (dev, pScreen, px, py, FALSE);
- }
- }
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12ScreenSetSize (ScreenPtr pScreen,
- CARD16 width,
- CARD16 height,
- CARD32 mmWidth,
- CARD32 mmHeight)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- WindowPtr pRoot = pScreen->root;
- PixmapPtr pScrnPix;
- Bool ret = FALSE;
- int c;
-
- if (xf86RandR12Key) {
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = pScrn->virtualX;
- randrp->virtualY = pScrn->virtualY;
- }
- }
- if (pRoot && pScrn->vtSema)
- (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
-
- /* Let the driver update virtualX and virtualY */
- if (!(*config->funcs->resize)(pScrn, width, height))
- goto finish;
-
- ret = TRUE;
- /* Update panning information */
- for (c = 0; c < config->num_crtc; c++) {
- xf86CrtcPtr crtc = config->crtc[c];
- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 ||
- crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
- if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1)
- crtc->panningTotalArea.x2 += width - pScreen->width;
- if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1)
- crtc->panningTotalArea.y2 += height - pScreen->height;
- if (crtc->panningTrackingArea.x2 > crtc->panningTrackingArea.x1)
- crtc->panningTrackingArea.x2 += width - pScreen->width;
- if (crtc->panningTrackingArea.y2 > crtc->panningTrackingArea.y1)
- crtc->panningTrackingArea.y2 += height - pScreen->height;
- xf86RandR13VerifyPanningArea (crtc, width, height);
- xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
- }
- }
-
- pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
- pScreen->width = pScrnPix->drawable.width = width;
- pScreen->height = pScrnPix->drawable.height = height;
- randrp->mmWidth = pScreen->mmWidth = mmWidth;
- randrp->mmHeight = pScreen->mmHeight = mmHeight;
-
- xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
- xf86SetViewport (pScreen, 0, 0);
-
-finish:
- if (pRoot && pScrn->vtSema)
- (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
-#if RANDR_12_INTERFACE
- if (xf86RandR12Key && pScreen->root && ret)
- RRScreenSizeNotify (pScreen);
-#endif
- return ret;
-}
-
-Rotation
-xf86RandR12GetRotation(ScreenPtr pScreen)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
- return randrp->rotation;
-}
-
-Bool
-xf86RandR12CreateScreenResources (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config;
- XF86RandRInfoPtr randrp;
- int c;
- int width, height;
- int mmWidth, mmHeight;
-#ifdef PANORAMIX
- /* XXX disable RandR when using Xinerama */
- if (!noPanoramiXExtension)
- return TRUE;
-#endif
-
- config = XF86_CRTC_CONFIG_PTR(pScrn);
- randrp = XF86RANDRINFO(pScreen);
- /*
- * Compute size of screen
- */
- width = 0; height = 0;
- for (c = 0; c < config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = config->crtc[c];
- int crtc_width = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
- int crtc_height = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
-
- if (crtc->enabled) {
- if (crtc_width > width)
- width = crtc_width;
- if (crtc_height > height)
- height = crtc_height;
- if (crtc->panningTotalArea.x2 > width)
- width = crtc->panningTotalArea.x2;
- if (crtc->panningTotalArea.y2 > height)
- height = crtc->panningTotalArea.y2;
- }
- }
-
- if (width && height)
- {
- /*
- * Compute physical size of screen
- */
- if (monitorResolution)
- {
- mmWidth = width * 25.4 / monitorResolution;
- mmHeight = height * 25.4 / monitorResolution;
- }
- else
- {
- xf86OutputPtr output = xf86CompatOutput(pScrn);
-
- if (output &&
- output->conf_monitor &&
- (output->conf_monitor->mon_width > 0 &&
- output->conf_monitor->mon_height > 0))
- {
- /*
- * Prefer user configured DisplaySize
- */
- mmWidth = output->conf_monitor->mon_width;
- mmHeight = output->conf_monitor->mon_height;
- }
- else
- {
- /*
- * Otherwise, just set the screen to DEFAULT_DPI
- */
- mmWidth = width * 25.4 / DEFAULT_DPI;
- mmHeight = height * 25.4 / DEFAULT_DPI;
- }
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Setting screen physical size to %d x %d\n",
- mmWidth, mmHeight);
- /*
- * This is the initial setting of the screen size.
- * We have to pre-set it here, otherwise panning would be adapted
- * to the new screen size.
- */
- pScreen->width = width;
- pScreen->height = height;
- xf86RandR12ScreenSetSize (pScreen,
- width,
- height,
- mmWidth,
- mmHeight);
- }
-
- if (xf86RandR12Key == NULL)
- return TRUE;
-
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = pScrn->virtualX;
- randrp->virtualY = pScrn->virtualY;
- }
- xf86CrtcSetScreenSubpixelOrder (pScreen);
-#if RANDR_12_INTERFACE
- if (xf86RandR12CreateScreenResources12 (pScreen))
- return TRUE;
-#endif
- return TRUE;
-}
-
-
-Bool
-xf86RandR12Init (ScreenPtr pScreen)
-{
- rrScrPrivPtr rp;
- XF86RandRInfoPtr randrp;
-
-#ifdef PANORAMIX
- /* XXX disable RandR when using Xinerama */
- if (!noPanoramiXExtension)
- {
- if (xf86NumScreens == 1)
- noPanoramiXExtension = TRUE;
- else
- return TRUE;
- }
-#endif
-
- if (xf86RandR12Generation != serverGeneration)
- xf86RandR12Generation = serverGeneration;
-
- xf86RandR12Key = &xf86RandR12KeyRec;
- if (!dixRegisterPrivateKey(&xf86RandR12KeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
-
- randrp = malloc(sizeof (XF86RandRInfoRec));
- if (!randrp)
- return FALSE;
-
- if (!RRScreenInit(pScreen))
- {
- free(randrp);
- return FALSE;
- }
- rp = rrGetScrPriv(pScreen);
- rp->rrGetInfo = xf86RandR12GetInfo;
- rp->rrSetConfig = xf86RandR12SetConfig;
-
- randrp->virtualX = -1;
- randrp->virtualY = -1;
- randrp->mmWidth = pScreen->mmWidth;
- randrp->mmHeight = pScreen->mmHeight;
-
- randrp->rotation = RR_Rotate_0; /* initial rotated mode */
-
- randrp->supported_rotations = RR_Rotate_0;
-
- randrp->maxX = randrp->maxY = 0;
-
- dixSetPrivate(&pScreen->devPrivates, xf86RandR12Key, randrp);
-
-#if RANDR_12_INTERFACE
- if (!xf86RandR12Init12 (pScreen))
- return FALSE;
-#endif
- return TRUE;
-}
-
-void
-xf86RandR12CloseScreen (ScreenPtr pScreen)
-{
- XF86RandRInfoPtr randrp;
-
- if (xf86RandR12Key == NULL)
- return;
-
- randrp = XF86RANDRINFO(pScreen);
-#if RANDR_12_INTERFACE
- xf86Screens[pScreen->myNum]->EnterVT = randrp->orig_EnterVT;
-#endif
-
- free(randrp);
-}
-
-void
-xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
-{
- XF86RandRInfoPtr randrp;
-#if RANDR_12_INTERFACE
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- int c;
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
-#endif
-
- if (xf86RandR12Key == NULL)
- return;
-
- randrp = XF86RANDRINFO(pScreen);
-#if RANDR_12_INTERFACE
- for (c = 0; c < config->num_crtc; c++) {
- xf86CrtcPtr crtc = config->crtc[c];
-
- RRCrtcSetRotations (crtc->randr_crtc, rotations);
- }
-#endif
- randrp->supported_rotations = rotations;
-}
-
-void
-xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms)
-{
- XF86RandRInfoPtr randrp;
-#if RANDR_13_INTERFACE
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- int c;
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
-#endif
-
- if (xf86RandR12Key == NULL)
- return;
-
- randrp = XF86RANDRINFO(pScreen);
-#if RANDR_13_INTERFACE
- for (c = 0; c < config->num_crtc; c++) {
- xf86CrtcPtr crtc = config->crtc[c];
-
- RRCrtcSetTransformSupport (crtc->randr_crtc, transforms);
- }
-#endif
-}
-
-void
-xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
-{
- ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-
- if (xf86RandR12Generation != serverGeneration ||
- XF86RANDRINFO(pScreen)->virtualX == -1)
- {
- *x = pScrn->virtualX;
- *y = pScrn->virtualY;
- } else {
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
- *x = randrp->virtualX;
- *y = randrp->virtualY;
- }
-}
-
-#if RANDR_12_INTERFACE
-
-#define FLAG_BITS (RR_HSyncPositive | \
- RR_HSyncNegative | \
- RR_VSyncPositive | \
- RR_VSyncNegative | \
- RR_Interlace | \
- RR_DoubleScan | \
- RR_CSync | \
- RR_CSyncPositive | \
- RR_CSyncNegative | \
- RR_HSkewPresent | \
- RR_BCast | \
- RR_PixelMultiplex | \
- RR_DoubleClock | \
- RR_ClockDivideBy2)
-
-static Bool
-xf86RandRModeMatches (RRModePtr randr_mode,
- DisplayModePtr mode)
-{
-#if 0
- if (match_name)
- {
- /* check for same name */
- int len = strlen (mode->name);
- if (randr_mode->mode.nameLength != len) return FALSE;
- if (memcmp (randr_mode->name, mode->name, len) != 0) return FALSE;
- }
-#endif
-
- /* check for same timings */
- if (randr_mode->mode.dotClock / 1000 != mode->Clock) return FALSE;
- if (randr_mode->mode.width != mode->HDisplay) return FALSE;
- if (randr_mode->mode.hSyncStart != mode->HSyncStart) return FALSE;
- if (randr_mode->mode.hSyncEnd != mode->HSyncEnd) return FALSE;
- if (randr_mode->mode.hTotal != mode->HTotal) return FALSE;
- if (randr_mode->mode.hSkew != mode->HSkew) return FALSE;
- if (randr_mode->mode.height != mode->VDisplay) return FALSE;
- if (randr_mode->mode.vSyncStart != mode->VSyncStart) return FALSE;
- if (randr_mode->mode.vSyncEnd != mode->VSyncEnd) return FALSE;
- if (randr_mode->mode.vTotal != mode->VTotal) return FALSE;
-
- /* check for same flags (using only the XF86 valid flag bits) */
- if ((randr_mode->mode.modeFlags & FLAG_BITS) != (mode->Flags & FLAG_BITS))
- return FALSE;
-
- /* everything matches */
- return TRUE;
-}
-
-static Bool
-xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
-{
- ScreenPtr pScreen = randr_crtc->pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- RRModePtr randr_mode = NULL;
- int x;
- int y;
- Rotation rotation;
- int numOutputs;
- RROutputPtr *randr_outputs;
- RROutputPtr randr_output;
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
- xf86OutputPtr output;
- int i, j;
- DisplayModePtr mode = &crtc->mode;
- Bool ret;
-
- randr_outputs = malloc(config->num_output * sizeof (RROutputPtr));
- if (!randr_outputs)
- return FALSE;
- x = crtc->x;
- y = crtc->y;
- rotation = crtc->rotation;
- numOutputs = 0;
- randr_mode = NULL;
- for (i = 0; i < config->num_output; i++)
- {
- output = config->output[i];
- if (output->crtc == crtc)
- {
- randr_output = output->randr_output;
- randr_outputs[numOutputs++] = randr_output;
- /*
- * We make copies of modes, so pointer equality
- * isn't sufficient
- */
- for (j = 0; j < randr_output->numModes + randr_output->numUserModes; j++)
- {
- RRModePtr m = (j < randr_output->numModes ?
- randr_output->modes[j] :
- randr_output->userModes[j-randr_output->numModes]);
-
- if (xf86RandRModeMatches (m, mode))
- {
- randr_mode = m;
- break;
- }
- }
- }
- }
- ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
- rotation,
- crtc->transformPresent ? &crtc->transform : NULL,
- numOutputs, randr_outputs);
- free(randr_outputs);
- return ret;
-}
-
-/*
- * Convert a RandR mode to a DisplayMode
- */
-static void
-xf86RandRModeConvert (ScrnInfoPtr scrn,
- RRModePtr randr_mode,
- DisplayModePtr mode)
-{
- memset(mode, 0, sizeof(DisplayModeRec));
- mode->status = MODE_OK;
-
- mode->Clock = randr_mode->mode.dotClock / 1000;
-
- mode->HDisplay = randr_mode->mode.width;
- mode->HSyncStart = randr_mode->mode.hSyncStart;
- mode->HSyncEnd = randr_mode->mode.hSyncEnd;
- mode->HTotal = randr_mode->mode.hTotal;
- mode->HSkew = randr_mode->mode.hSkew;
-
- mode->VDisplay = randr_mode->mode.height;
- mode->VSyncStart = randr_mode->mode.vSyncStart;
- mode->VSyncEnd = randr_mode->mode.vSyncEnd;
- mode->VTotal = randr_mode->mode.vTotal;
- mode->VScan = 0;
-
- mode->Flags = randr_mode->mode.modeFlags & FLAG_BITS;
-
- xf86SetModeCrtc (mode, scrn->adjustFlags);
-}
-
-static Bool
-xf86RandR12CrtcSet (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc,
- RRModePtr randr_mode,
- int x,
- int y,
- Rotation rotation,
- int num_randr_outputs,
- RROutputPtr *randr_outputs)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
- RRTransformPtr transform;
- Bool changed = FALSE;
- int o, ro;
- xf86CrtcPtr *save_crtcs;
- Bool save_enabled = crtc->enabled;
-
- if (!crtc->scrn->vtSema)
- return FALSE;
-
- save_crtcs = malloc(config->num_output * sizeof (xf86CrtcPtr));
- if ((randr_mode != NULL) != crtc->enabled)
- changed = TRUE;
- else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode))
- changed = TRUE;
-
- if (rotation != crtc->rotation)
- changed = TRUE;
-
- transform = RRCrtcGetTransform (randr_crtc);
- if ((transform != NULL) != crtc->transformPresent)
- changed = TRUE;
- else if (transform && memcmp (&transform->transform, &crtc->transform.transform,
- sizeof (transform->transform)) != 0)
- changed = TRUE;
-
- if (x != crtc->x || y != crtc->y)
- changed = TRUE;
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- xf86CrtcPtr new_crtc;
-
- save_crtcs[o] = output->crtc;
-
- if (output->crtc == crtc)
- new_crtc = NULL;
- else
- new_crtc = output->crtc;
- for (ro = 0; ro < num_randr_outputs; ro++)
- if (output->randr_output == randr_outputs[ro])
- {
- new_crtc = crtc;
- break;
- }
- if (new_crtc != output->crtc)
- {
- changed = TRUE;
- output->crtc = new_crtc;
- }
- }
- for (ro = 0; ro < num_randr_outputs; ro++)
- if (randr_outputs[ro]->pendingProperties)
- changed = TRUE;
-
- /* XXX need device-independent mode setting code through an API */
- if (changed)
- {
- crtc->enabled = randr_mode != NULL;
-
- if (randr_mode)
- {
- DisplayModeRec mode;
- RRTransformPtr transform = RRCrtcGetTransform (randr_crtc);
-
- xf86RandRModeConvert (pScrn, randr_mode, &mode);
- if (!xf86CrtcSetModeTransform (crtc, &mode, rotation, transform, x, y))
- {
- crtc->enabled = save_enabled;
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- output->crtc = save_crtcs[o];
- }
- free(save_crtcs);
- return FALSE;
- }
- xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height);
- xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
- /*
- * Save the last successful setting for EnterVT
- */
- crtc->desiredMode = mode;
- crtc->desiredRotation = rotation;
- if (transform) {
- crtc->desiredTransform = *transform;
- crtc->desiredTransformPresent = TRUE;
- } else
- crtc->desiredTransformPresent = FALSE;
-
- crtc->desiredX = x;
- crtc->desiredY = y;
- }
- xf86DisableUnusedFunctions (pScrn);
- }
- free(save_crtcs);
- return xf86RandR12CrtcNotify (randr_crtc);
-}
-
-static Bool
-xf86RandR12CrtcSetGamma (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc)
-{
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
-
- if (crtc->funcs->gamma_set == NULL)
- return FALSE;
-
- if (!crtc->scrn->vtSema)
- return TRUE;
-
- /* Realloc local gamma if needed. */
- if (randr_crtc->gammaSize != crtc->gamma_size) {
- CARD16 *tmp_ptr;
- tmp_ptr = realloc(crtc->gamma_red, 3 * crtc->gamma_size * sizeof (CARD16));
- if (!tmp_ptr)
- return FALSE;
- crtc->gamma_red = tmp_ptr;
- crtc->gamma_green = crtc->gamma_red + crtc->gamma_size;
- crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size;
- }
-
- crtc->gamma_size = randr_crtc->gammaSize;
- memcpy (crtc->gamma_red, randr_crtc->gammaRed, crtc->gamma_size * sizeof (CARD16));
- memcpy (crtc->gamma_green, randr_crtc->gammaGreen, crtc->gamma_size * sizeof (CARD16));
- memcpy (crtc->gamma_blue, randr_crtc->gammaBlue, crtc->gamma_size * sizeof (CARD16));
-
- /* Only set it when the crtc is actually running.
- * Otherwise it will be set when it's activated.
- */
- if (crtc->active)
- crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
- crtc->gamma_blue, crtc->gamma_size);
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12CrtcGetGamma (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc)
-{
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
-
- if (!crtc->gamma_size)
- return FALSE;
-
- if (!crtc->gamma_red || !crtc->gamma_green || !crtc->gamma_blue)
- return FALSE;
-
- /* Realloc randr gamma if needed. */
- if (randr_crtc->gammaSize != crtc->gamma_size) {
- CARD16 *tmp_ptr;
- tmp_ptr = realloc(randr_crtc->gammaRed, 3 * crtc->gamma_size * sizeof (CARD16));
- if (!tmp_ptr)
- return FALSE;
- randr_crtc->gammaRed = tmp_ptr;
- randr_crtc->gammaGreen = randr_crtc->gammaRed + crtc->gamma_size;
- randr_crtc->gammaBlue = randr_crtc->gammaGreen + crtc->gamma_size;
- }
- randr_crtc->gammaSize = crtc->gamma_size;
- memcpy (randr_crtc->gammaRed, crtc->gamma_red, crtc->gamma_size * sizeof (CARD16));
- memcpy (randr_crtc->gammaGreen, crtc->gamma_green, crtc->gamma_size * sizeof (CARD16));
- memcpy (randr_crtc->gammaBlue, crtc->gamma_blue, crtc->gamma_size * sizeof (CARD16));
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12OutputSetProperty (ScreenPtr pScreen,
- RROutputPtr randr_output,
- Atom property,
- RRPropertyValuePtr value)
-{
- xf86OutputPtr output = randr_output->devPrivate;
-
- /* If we don't have any property handler, then we don't care what the
- * user is setting properties to.
- */
- if (output->funcs->set_property == NULL)
- return TRUE;
-
- /*
- * This function gets called even when vtSema is FALSE, as
- * drivers will need to remember the correct value to apply
- * when the VT switch occurs
- */
- return output->funcs->set_property(output, property, value);
-}
-
-static Bool
-xf86RandR13OutputGetProperty (ScreenPtr pScreen,
- RROutputPtr randr_output,
- Atom property)
-{
- xf86OutputPtr output = randr_output->devPrivate;
-
- if (output->funcs->get_property == NULL)
- return TRUE;
-
- /* Should be safe even w/o vtSema */
- return output->funcs->get_property(output, property);
-}
-
-static Bool
-xf86RandR12OutputValidateMode (ScreenPtr pScreen,
- RROutputPtr randr_output,
- RRModePtr randr_mode)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86OutputPtr output = randr_output->devPrivate;
- DisplayModeRec mode;
-
- xf86RandRModeConvert (pScrn, randr_mode, &mode);
- /*
- * This function may be called when vtSema is FALSE, so
- * the underlying function must either avoid touching the hardware
- * or return FALSE when vtSema is FALSE
- */
- if (output->funcs->mode_valid (output, &mode) != MODE_OK)
- return FALSE;
- return TRUE;
-}
-
-static void
-xf86RandR12ModeDestroy (ScreenPtr pScreen, RRModePtr randr_mode)
-{
-}
-
-/**
- * Given a list of xf86 modes and a RandR Output object, construct
- * RandR modes and assign them to the output
- */
-static Bool
-xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
-{
- DisplayModePtr mode;
- RRModePtr *rrmodes = NULL;
- int nmode = 0;
- int npreferred = 0;
- Bool ret = TRUE;
- int pref;
-
- for (mode = modes; mode; mode = mode->next)
- nmode++;
-
- if (nmode) {
- rrmodes = malloc(nmode * sizeof (RRModePtr));
-
- if (!rrmodes)
- return FALSE;
- nmode = 0;
-
- for (pref = 1; pref >= 0; pref--) {
- for (mode = modes; mode; mode = mode->next) {
- if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) {
- xRRModeInfo modeInfo;
- RRModePtr rrmode;
-
- modeInfo.nameLength = strlen (mode->name);
- modeInfo.width = mode->HDisplay;
- modeInfo.dotClock = mode->Clock * 1000;
- modeInfo.hSyncStart = mode->HSyncStart;
- modeInfo.hSyncEnd = mode->HSyncEnd;
- modeInfo.hTotal = mode->HTotal;
- modeInfo.hSkew = mode->HSkew;
-
- modeInfo.height = mode->VDisplay;
- modeInfo.vSyncStart = mode->VSyncStart;
- modeInfo.vSyncEnd = mode->VSyncEnd;
- modeInfo.vTotal = mode->VTotal;
- modeInfo.modeFlags = mode->Flags;
-
- rrmode = RRModeGet (&modeInfo, mode->name);
- if (rrmode) {
- rrmodes[nmode++] = rrmode;
- npreferred += pref;
- }
- }
- }
- }
- }
-
- ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred);
- free(rrmodes);
- return ret;
-}
-
-/*
- * Mirror the current mode configuration to RandR
- */
-static Bool
-xf86RandR12SetInfo12 (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- RROutputPtr *clones;
- RRCrtcPtr *crtcs;
- int ncrtc;
- int o, c, l;
- RRCrtcPtr randr_crtc;
- int nclone;
-
- clones = malloc(config->num_output * sizeof (RROutputPtr));
- crtcs = malloc(config->num_crtc * sizeof (RRCrtcPtr));
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
-
- ncrtc = 0;
- for (c = 0; c < config->num_crtc; c++)
- if (output->possible_crtcs & (1 << c))
- crtcs[ncrtc++] = config->crtc[c]->randr_crtc;
-
- if (output->crtc)
- randr_crtc = output->crtc->randr_crtc;
- else
- randr_crtc = NULL;
-
- if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc))
- {
- free(crtcs);
- free(clones);
- return FALSE;
- }
-
- RROutputSetPhysicalSize(output->randr_output,
- output->mm_width,
- output->mm_height);
- xf86RROutputSetModes (output->randr_output, output->probed_modes);
-
- switch (output->status) {
- case XF86OutputStatusConnected:
- RROutputSetConnection (output->randr_output, RR_Connected);
- break;
- case XF86OutputStatusDisconnected:
- RROutputSetConnection (output->randr_output, RR_Disconnected);
- break;
- case XF86OutputStatusUnknown:
- RROutputSetConnection (output->randr_output, RR_UnknownConnection);
- break;
- }
-
- RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order);
-
- /*
- * Valid clones
- */
- nclone = 0;
- for (l = 0; l < config->num_output; l++)
- {
- xf86OutputPtr clone = config->output[l];
-
- if (l != o && (output->possible_clones & (1 << l)))
- clones[nclone++] = clone->randr_output;
- }
- if (!RROutputSetClones (output->randr_output, clones, nclone))
- {
- free(crtcs);
- free(clones);
- return FALSE;
- }
- }
- free(crtcs);
- free(clones);
- return TRUE;
-}
-
-
-
-/*
- * Query the hardware for the current state, then mirror
- * that to RandR
- */
-static Bool
-xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
- if (!pScrn->vtSema)
- return TRUE;
- xf86ProbeOutputModes (pScrn, 0, 0);
- xf86SetScrnInfoModes (pScrn);
- return xf86RandR12SetInfo12 (pScreen);
-}
-
-static Bool
-xf86RandR12CreateObjects12 (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
- int o;
-
- if (!RRInit ())
- return FALSE;
-
- /*
- * Configure crtcs
- */
- for (c = 0; c < config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = config->crtc[c];
-
- crtc->randr_crtc = RRCrtcCreate (pScreen, crtc);
- RRCrtcGammaSetSize (crtc->randr_crtc, 256);
- }
- /*
- * Configure outputs
- */
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
-
- output->randr_output = RROutputCreate (pScreen, output->name,
- strlen (output->name),
- output);
-
- if (output->funcs->create_resources != NULL)
- output->funcs->create_resources(output);
- RRPostPendingProperties (output->randr_output);
- }
- return TRUE;
-}
-
-static Bool
-xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
-{
- int c;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
-
- if (xf86RandR12Key == NULL)
- return TRUE;
-
- for (c = 0; c < config->num_crtc; c++)
- xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
-
- RRScreenSetSizeRange (pScreen, config->minWidth, config->minHeight,
- config->maxWidth, config->maxHeight);
- return TRUE;
-}
-
-/*
- * Something happened within the screen configuration due
- * to DGA, VidMode or hot key. Tell RandR
- */
-
-void
-xf86RandR12TellChanged (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
-
- if (xf86RandR12Key == NULL)
- return;
-
- xf86RandR12SetInfo12 (pScreen);
- for (c = 0; c < config->num_crtc; c++)
- xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
-
- RRTellChanged (pScreen);
-}
-
-static void
-xf86RandR12PointerMoved (int scrnIndex, int x, int y)
-{
- ScreenPtr pScreen = screenInfo.screens[scrnIndex];
- ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- int c;
-
- randrp->pointerX = x;
- randrp->pointerY = y;
- for (c = 0; c < config->num_crtc; c++)
- xf86RandR13Pan (config->crtc[c], x, y);
-}
-
-static Bool
-xf86RandR13GetPanning (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc,
- BoxPtr totalArea,
- BoxPtr trackingArea,
- INT16 *border)
-{
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
-
- if (crtc->version < 2)
- return FALSE;
- if (totalArea)
- memcpy (totalArea, &crtc->panningTotalArea, sizeof(BoxRec));
- if (trackingArea)
- memcpy (trackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
- if (border)
- memcpy (border, crtc->panningBorder, 4*sizeof(INT16));
-
- return TRUE;
-}
-
-static Bool
-xf86RandR13SetPanning (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc,
- BoxPtr totalArea,
- BoxPtr trackingArea,
- INT16 *border)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
- BoxRec oldTotalArea;
- BoxRec oldTrackingArea;
- INT16 oldBorder[4];
-
-
- if (crtc->version < 2)
- return FALSE;
-
- memcpy (&oldTotalArea, &crtc->panningTotalArea, sizeof(BoxRec));
- memcpy (&oldTrackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
- memcpy (oldBorder, crtc->panningBorder, 4*sizeof(INT16));
-
- if (totalArea)
- memcpy (&crtc->panningTotalArea, totalArea, sizeof(BoxRec));
- if (trackingArea)
- memcpy (&crtc->panningTrackingArea, trackingArea, sizeof(BoxRec));
- if (border)
- memcpy (crtc->panningBorder, border, 4*sizeof(INT16));
-
- if (xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height)) {
- xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
- return TRUE;
- } else {
- /* Restore old settings */
- memcpy (&crtc->panningTotalArea, &oldTotalArea, sizeof(BoxRec));
- memcpy (&crtc->panningTrackingArea, &oldTrackingArea, sizeof(BoxRec));
- memcpy (crtc->panningBorder, oldBorder, 4*sizeof(INT16));
- return FALSE;
- }
-}
-
-/*
- * Compatibility with XF86VidMode's gamma changer. This necessarily clobbers
- * any per-crtc setup. You asked for it...
- */
-
-static void
-gamma_to_ramp(float gamma, CARD16 *ramp, int size)
-{
- int i;
-
- for (i = 0; i < size; i++) {
- if (gamma == 1.0)
- ramp[i] = i << 8;
- else
- ramp[i] = (CARD16)(pow((double)i / (double)(size - 1), 1. / gamma)
- * (double)(size - 1) * 256);
- }
-}
-
-static int
-xf86RandR12ChangeGamma(int scrnIndex, Gamma gamma)
-{
- CARD16 *points, *red, *green, *blue;
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
- int size;
-
- if (!crtc)
- return Success;
-
- size = max(0, crtc->gammaSize);
- if (!size)
- return Success;
-
- points = calloc(size, 3 * sizeof(CARD16));
- if (!points)
- return BadAlloc;
-
- red = points;
- green = points + size;
- blue = points + 2 * size;
-
- gamma_to_ramp(gamma.red, red, size);
- gamma_to_ramp(gamma.green, green, size);
- gamma_to_ramp(gamma.blue, blue, size);
- RRCrtcGammaSet(crtc, red, green, blue);
-
- free(points);
-
- pScrn->gamma = gamma;
-
- return Success;
-}
-
-static Bool
-xf86RandR12EnterVT (int screen_index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[screen_index];
- ScrnInfoPtr pScrn = xf86Screens[screen_index];
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- rrScrPrivPtr rp = rrGetScrPriv(pScreen);
- Bool ret;
- int i;
-
- if (randrp->orig_EnterVT) {
- pScrn->EnterVT = randrp->orig_EnterVT;
- ret = pScrn->EnterVT (screen_index, flags);
- randrp->orig_EnterVT = pScrn->EnterVT;
- pScrn->EnterVT = xf86RandR12EnterVT;
- if (!ret)
- return FALSE;
- }
-
- /* reload gamma */
- for (i = 0; i < rp->numCrtcs; i++)
- xf86RandR12CrtcSetGamma(pScreen, rp->crtcs[i]);
-
- return RRGetInfo (pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */
-}
-
-static Bool
-xf86RandR12Init12 (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- rrScrPrivPtr rp = rrGetScrPriv(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- int i;
-
- rp->rrGetInfo = xf86RandR12GetInfo12;
- rp->rrScreenSetSize = xf86RandR12ScreenSetSize;
- rp->rrCrtcSet = xf86RandR12CrtcSet;
- rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
- rp->rrCrtcGetGamma = xf86RandR12CrtcGetGamma;
- rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
- rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
-#if RANDR_13_INTERFACE
- rp->rrOutputGetProperty = xf86RandR13OutputGetProperty;
- rp->rrGetPanning = xf86RandR13GetPanning;
- rp->rrSetPanning = xf86RandR13SetPanning;
-#endif
- rp->rrModeDestroy = xf86RandR12ModeDestroy;
- rp->rrSetConfig = NULL;
- pScrn->PointerMoved = xf86RandR12PointerMoved;
- pScrn->ChangeGamma = xf86RandR12ChangeGamma;
-
- randrp->orig_EnterVT = pScrn->EnterVT;
- pScrn->EnterVT = xf86RandR12EnterVT;
-
- if (!xf86RandR12CreateObjects12 (pScreen))
- return FALSE;
-
- /*
- * Configure output modes
- */
- if (!xf86RandR12SetInfo12 (pScreen))
- return FALSE;
- for (i = 0; i < rp->numCrtcs; i++) {
- xf86RandR12CrtcGetGamma(pScreen, rp->crtcs[i]);
- }
- return TRUE;
-}
-
-#endif
-
-Bool
-xf86RandR12PreInit (ScrnInfoPtr pScrn)
-{
- return TRUE;
-}
+/*
+ * Copyright © 2002 Keith Packard, member of 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 name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The 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 COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE 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.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#else
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#endif
+
+#include "xf86.h"
+#include "os.h"
+#include "globals.h"
+#include "xf86Priv.h"
+#include "xf86DDC.h"
+#include "mipointer.h"
+#include "windowstr.h"
+#include "inputstr.h"
+#include <randrstr.h>
+#include <X11/extensions/render.h>
+
+#include "xf86Crtc.h"
+#include "xf86RandR12.h"
+
+typedef struct _xf86RandR12Info {
+ int virtualX;
+ int virtualY;
+ int mmWidth;
+ int mmHeight;
+ int maxX;
+ int maxY;
+ int pointerX;
+ int pointerY;
+ Rotation rotation; /* current mode */
+ Rotation supported_rotations; /* driver supported */
+
+ /* Used to wrap EnterVT so we can re-probe the outputs when a laptop unsuspends
+ * (actually, any time that we switch back into our VT).
+ *
+ * See https://bugs.freedesktop.org/show_bug.cgi?id=21554
+ */
+ xf86EnterVTProc *orig_EnterVT;
+} XF86RandRInfoRec, *XF86RandRInfoPtr;
+
+#ifdef RANDR_12_INTERFACE
+static Bool xf86RandR12Init12 (ScreenPtr pScreen);
+static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen);
+#endif
+
+static int xf86RandR12Generation;
+
+static DevPrivateKeyRec xf86RandR12KeyRec;
+static DevPrivateKey xf86RandR12Key;
+#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \
+ dixLookupPrivate(&(p)->devPrivates, xf86RandR12Key))
+
+
+static int
+xf86RandR12ModeRefresh (DisplayModePtr mode)
+{
+ if (mode->VRefresh)
+ return (int) (mode->VRefresh + 0.5);
+ else
+ return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
+}
+
+/* Adapt panning area; return TRUE if panning area was valid without adaption */
+static int
+xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeight)
+{
+ int ret = TRUE;
+
+ if (crtc->version < 2)
+ return FALSE;
+
+ if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1) {
+ /* Panning in X is disabled */
+ if (crtc->panningTotalArea.x1 || crtc->panningTotalArea.x2)
+ /* Illegal configuration -> fail/disable */
+ ret = FALSE;
+ crtc->panningTotalArea.x1 = crtc->panningTotalArea.x2 = 0;
+ crtc->panningTrackingArea.x1 = crtc->panningTrackingArea.x2 = 0;
+ crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
+ } else {
+ /* Panning in X is enabled */
+ if (crtc->panningTotalArea.x1 < 0) {
+ /* Panning region outside screen -> move inside */
+ crtc->panningTotalArea.x2 -= crtc->panningTotalArea.x1;
+ crtc->panningTotalArea.x1 = 0;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay) {
+ /* Panning region smaller than displayed area -> crop to displayed area */
+ crtc->panningTotalArea.x2 = crtc->panningTotalArea.x1 + crtc->mode.HDisplay;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.x2 > screenWidth) {
+ /* Panning region larger than screen -> move inside, then crop to screen */
+ crtc->panningTotalArea.x1 -= crtc->panningTotalArea.x2 - screenWidth;
+ crtc->panningTotalArea.x2 = screenWidth;
+ ret = FALSE;
+ if (crtc->panningTotalArea.x1 < 0)
+ crtc->panningTotalArea.x1 = 0;
+ }
+ if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay) {
+ /* Borders too large -> set to 0 */
+ crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
+ ret = FALSE;
+ }
+ }
+
+ if (crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) {
+ /* Panning in Y is disabled */
+ if (crtc->panningTotalArea.y1 || crtc->panningTotalArea.y2)
+ /* Illegal configuration -> fail/disable */
+ ret = FALSE;
+ crtc->panningTotalArea.y1 = crtc->panningTotalArea.y2 = 0;
+ crtc->panningTrackingArea.y1 = crtc->panningTrackingArea.y2 = 0;
+ crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
+ } else {
+ /* Panning in Y is enabled */
+ if (crtc->panningTotalArea.y1 < 0) {
+ /* Panning region outside screen -> move inside */
+ crtc->panningTotalArea.y2 -= crtc->panningTotalArea.y1;
+ crtc->panningTotalArea.y1 = 0;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay) {
+ /* Panning region smaller than displayed area -> crop to displayed area */
+ crtc->panningTotalArea.y2 = crtc->panningTotalArea.y1 + crtc->mode.VDisplay;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.y2 > screenHeight) {
+ /* Panning region larger than screen -> move inside, then crop to screen */
+ crtc->panningTotalArea.y1 -= crtc->panningTotalArea.y2 - screenHeight;
+ crtc->panningTotalArea.y2 = screenHeight;
+ ret = FALSE;
+ if (crtc->panningTotalArea.y1 < 0)
+ crtc->panningTotalArea.y1 = 0;
+ }
+ if (crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) {
+ /* Borders too large -> set to 0 */
+ crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
+ ret = FALSE;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * The heart of the panning operation:
+ *
+ * Given a frame buffer position (fb_x, fb_y),
+ * and a crtc position (crtc_x, crtc_y),
+ * and a transform matrix which maps frame buffer to crtc,
+ * compute a panning position (pan_x, pan_y) that
+ * makes the resulting transform line those two up
+ */
+
+static void
+xf86ComputeCrtcPan (Bool transform_in_use,
+ struct pixman_f_transform *m,
+ double screen_x, double screen_y,
+ double crtc_x, double crtc_y,
+ int old_pan_x, int old_pan_y,
+ int *new_pan_x, int *new_pan_y)
+{
+ if (transform_in_use) {
+ /*
+ * Given the current transform, M, the current position
+ * on the Screen, S, and the desired position on the CRTC,
+ * C, compute a translation, T, such that:
+ *
+ * M T S = C
+ *
+ * where T is of the form
+ *
+ * | 1 0 dx |
+ * | 0 1 dy |
+ * | 0 0 1 |
+ *
+ * M T S =
+ * | M00 Sx + M01 Sy + M00 dx + M01 dy + M02 | | Cx F |
+ * | M10 Sx + M11 Sy + M10 dx + M11 dy + M12 | = | Cy F |
+ * | M20 Sx + M21 Sy + M20 dx + M21 dy + M22 | | F |
+ *
+ * R = M S
+ *
+ * Cx F = M00 dx + M01 dy + R0
+ * Cy F = M10 dx + M11 dy + R1
+ * F = M20 dx + M21 dy + R2
+ *
+ * Zero out dx, then dy
+ *
+ * F (Cx M10 - Cy M00) =
+ * (M10 M01 - M00 M11) dy + M10 R0 - M00 R1
+ * F (M10 - Cy M20) =
+ * (M10 M21 - M20 M11) dy + M10 R2 - M20 R1
+ *
+ * F (Cx M11 - Cy M01) =
+ * (M11 M00 - M01 M10) dx + M11 R0 - M01 R1
+ * F (M11 - Cy M21) =
+ * (M11 M20 - M21 M10) dx + M11 R2 - M21 R1
+ *
+ * Make some temporaries
+ *
+ * T = | Cx M10 - Cy M00 |
+ * | Cx M11 - Cy M01 |
+ *
+ * U = | M10 M01 - M00 M11 |
+ * | M11 M00 - M01 M10 |
+ *
+ * Q = | M10 R0 - M00 R1 |
+ * | M11 R0 - M01 R1 |
+ *
+ * P = | M10 - Cy M20 |
+ * | M11 - Cy M21 |
+ *
+ * W = | M10 M21 - M20 M11 |
+ * | M11 M20 - M21 M10 |
+ *
+ * V = | M10 R2 - M20 R1 |
+ * | M11 R2 - M21 R1 |
+ *
+ * Rewrite:
+ *
+ * F T0 = U0 dy + Q0
+ * F P0 = W0 dy + V0
+ * F T1 = U1 dx + Q1
+ * F P1 = W1 dx + V1
+ *
+ * Solve for F (two ways)
+ *
+ * F (W0 T0 - U0 P0) = W0 Q0 - U0 V0
+ *
+ * W0 Q0 - U0 V0
+ * F = -------------
+ * W0 T0 - U0 P0
+ *
+ * F (W1 T1 - U1 P1) = W1 Q1 - U1 V1
+ *
+ * W1 Q1 - U1 V1
+ * F = -------------
+ * W1 T1 - U1 P1
+ *
+ * We'll use which ever solution works (denominator != 0)
+ *
+ * Finally, solve for dx and dy:
+ *
+ * dx = (F T1 - Q1) / U1
+ * dx = (F P1 - V1) / W1
+ *
+ * dy = (F T0 - Q0) / U0
+ * dy = (F P0 - V0) / W0
+ */
+ double r[3];
+ double q[2], u[2], t[2], v[2], w[2], p[2];
+ double f;
+ struct pict_f_vector d;
+ int i;
+
+ /* Get the un-normalized crtc coordinates again */
+ for (i = 0; i < 3; i++)
+ r[i] = m->m[i][0] * screen_x + m->m[i][1] * screen_y + m->m[i][2];
+
+ /* Combine values into temporaries */
+ for (i = 0; i < 2; i++) {
+ q[i] = m->m[1][i] * r[0] - m->m[0][i] * r[1];
+ u[i] = m->m[1][i] * m->m[0][1-i] - m->m[0][i] * m->m[1][1-i];
+ t[i] = m->m[1][i] * crtc_x - m->m[0][i] * crtc_y;
+
+ v[i] = m->m[1][i] * r[2] - m->m[2][i] * r[1];
+ w[i] = m->m[1][i] * m->m[2][1-i] - m->m[2][i] * m->m[1][1-i];
+ p[i] = m->m[1][i] - m->m[2][i] * crtc_y;
+ }
+
+ /* Find a way to compute f */
+ f = 0;
+ for (i = 0; i < 2; i++) {
+ double a = w[i] * q[i] - u[i] * v[i];
+ double b = w[i] * t[i] - u[i] * p[i];
+ if (b != 0) {
+ f = a/b;
+ break;
+ }
+ }
+
+ /* Solve for the resulting transform vector */
+ for (i = 0; i < 2; i++) {
+ if (u[i])
+ d.v[1-i] = (t[i] * f - q[i]) / u[i];
+ else if (w[1])
+ d.v[1-i] = (p[i] * f - v[i]) / w[i];
+ else
+ d.v[1-i] = 0;
+ }
+ *new_pan_x = old_pan_x - floor (d.v[0] + 0.5);
+ *new_pan_y = old_pan_y - floor (d.v[1] + 0.5);
+ } else {
+ *new_pan_x = screen_x - crtc_x;
+ *new_pan_y = screen_y - crtc_y;
+ }
+}
+
+static void
+xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
+{
+ int newX, newY;
+ int width, height;
+ Bool panned = FALSE;
+
+ if (crtc->version < 2)
+ return;
+
+ if (! crtc->enabled ||
+ (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 &&
+ crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1))
+ return;
+
+ newX = crtc->x;
+ newY = crtc->y;
+ width = crtc->mode.HDisplay;
+ height = crtc->mode.VDisplay;
+
+ if ((crtc->panningTrackingArea.x2 <= crtc->panningTrackingArea.x1 ||
+ (x >= crtc->panningTrackingArea.x1 && x < crtc->panningTrackingArea.x2)) &&
+ (crtc->panningTrackingArea.y2 <= crtc->panningTrackingArea.y1 ||
+ (y >= crtc->panningTrackingArea.y1 && y < crtc->panningTrackingArea.y2)))
+ {
+ struct pict_f_vector c;
+
+ /*
+ * Pre-clip the mouse position to the panning area so that we don't
+ * push the crtc outside. This doesn't deal with changes to the
+ * panning values, only mouse position changes.
+ */
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1)
+ {
+ if (x < crtc->panningTotalArea.x1)
+ x = crtc->panningTotalArea.x1;
+ if (x >= crtc->panningTotalArea.x2)
+ x = crtc->panningTotalArea.x2 - 1;
+ }
+ if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1)
+ {
+ if (y < crtc->panningTotalArea.y1)
+ y = crtc->panningTotalArea.y1;
+ if (y >= crtc->panningTotalArea.y2)
+ y = crtc->panningTotalArea.y2 - 1;
+ }
+
+ c.v[0] = x;
+ c.v[1] = y;
+ c.v[2] = 1.0;
+ if (crtc->transform_in_use) {
+ pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &c);
+ } else {
+ c.v[0] -= crtc->x;
+ c.v[1] -= crtc->y;
+ }
+
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
+ if (c.v[0] < crtc->panningBorder[0]) {
+ c.v[0] = crtc->panningBorder[0];
+ panned = TRUE;
+ }
+ if (c.v[0] >= width - crtc->panningBorder[2]) {
+ c.v[0] = width - crtc->panningBorder[2] - 1;
+ panned = TRUE;
+ }
+ }
+ if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+ if (c.v[1] < crtc->panningBorder[1]) {
+ c.v[1] = crtc->panningBorder[1];
+ panned = TRUE;
+ }
+ if (c.v[1] >= height - crtc->panningBorder[3]) {
+ c.v[1] = height - crtc->panningBorder[3] - 1;
+ panned = TRUE;
+ }
+ }
+ if (panned)
+ xf86ComputeCrtcPan (crtc->transform_in_use,
+ &crtc->f_framebuffer_to_crtc,
+ x, y, c.v[0], c.v[1],
+ newX, newY, &newX, &newY);
+ }
+
+ /*
+ * Ensure that the crtc is within the panning region.
+ *
+ * XXX This computation only works when we do not have a transform
+ * in use.
+ */
+ if (!crtc->transform_in_use)
+ {
+ /* Validate against [xy]1 after [xy]2, to be sure that results are > 0 for [xy]1 > 0 */
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
+ if (newX > crtc->panningTotalArea.x2 - width)
+ newX = crtc->panningTotalArea.x2 - width;
+ if (newX < crtc->panningTotalArea.x1)
+ newX = crtc->panningTotalArea.x1;
+ }
+ if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+ if (newY > crtc->panningTotalArea.y2 - height)
+ newY = crtc->panningTotalArea.y2 - height;
+ if (newY < crtc->panningTotalArea.y1)
+ newY = crtc->panningTotalArea.y1;
+ }
+ }
+ if (newX != crtc->x || newY != crtc->y)
+ xf86CrtcSetOrigin (crtc, newX, newY);
+}
+
+static Bool
+xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ RRScreenSizePtr pSize;
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ DisplayModePtr mode;
+ int refresh0 = 60;
+ int maxX = 0, maxY = 0;
+
+ *rotations = randrp->supported_rotations;
+
+ if (randrp->virtualX == -1 || randrp->virtualY == -1)
+ {
+ randrp->virtualX = scrp->virtualX;
+ randrp->virtualY = scrp->virtualY;
+ }
+
+ /* Re-probe the outputs for new monitors or modes */
+ if (scrp->vtSema)
+ {
+ xf86ProbeOutputModes (scrp, 0, 0);
+ xf86SetScrnInfoModes (scrp);
+ }
+
+ for (mode = scrp->modes; ; mode = mode->next)
+ {
+ int refresh = xf86RandR12ModeRefresh (mode);
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ if (maxX < mode->HDisplay)
+ maxX = mode->HDisplay;
+ if (maxY < mode->VDisplay)
+ maxY = mode->VDisplay;
+ }
+ if (mode == scrp->modes)
+ refresh0 = refresh;
+ pSize = RRRegisterSize (pScreen,
+ mode->HDisplay, mode->VDisplay,
+ randrp->mmWidth, randrp->mmHeight);
+ if (!pSize)
+ return FALSE;
+ RRRegisterRate (pScreen, pSize, refresh);
+
+ if (xf86ModesEqual(mode, scrp->currentMode))
+ {
+ RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
+ }
+ if (mode->next == scrp->modes)
+ break;
+ }
+
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ randrp->maxX = maxX;
+ randrp->maxY = maxY;
+ }
+
+ return TRUE;
+}
+
+static Bool
+xf86RandR12SetMode (ScreenPtr pScreen,
+ DisplayModePtr mode,
+ Bool useVirtual,
+ int mmWidth,
+ int mmHeight)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ int oldWidth = pScreen->width;
+ int oldHeight = pScreen->height;
+ int oldmmWidth = pScreen->mmWidth;
+ int oldmmHeight = pScreen->mmHeight;
+ WindowPtr pRoot = pScreen->root;
+ DisplayModePtr currentMode = NULL;
+ Bool ret = TRUE;
+
+ if (pRoot)
+ (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
+ if (useVirtual)
+ {
+ scrp->virtualX = randrp->virtualX;
+ scrp->virtualY = randrp->virtualY;
+ }
+ else
+ {
+ scrp->virtualX = mode->HDisplay;
+ scrp->virtualY = mode->VDisplay;
+ }
+
+ if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
+ {
+ /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
+ pScreen->width = scrp->virtualY;
+ pScreen->height = scrp->virtualX;
+ pScreen->mmWidth = mmHeight;
+ pScreen->mmHeight = mmWidth;
+ }
+ else
+ {
+ pScreen->width = scrp->virtualX;
+ pScreen->height = scrp->virtualY;
+ pScreen->mmWidth = mmWidth;
+ pScreen->mmHeight = mmHeight;
+ }
+ if (scrp->currentMode == mode) {
+ /* Save current mode */
+ currentMode = scrp->currentMode;
+ /* Reset, just so we ensure the drivers SwitchMode is called */
+ scrp->currentMode = NULL;
+ }
+ /*
+ * We know that if the driver failed to SwitchMode to the rotated
+ * version, then it should revert back to it's prior mode.
+ */
+ if (!xf86SwitchMode (pScreen, mode))
+ {
+ ret = FALSE;
+ scrp->virtualX = pScreen->width = oldWidth;
+ scrp->virtualY = pScreen->height = oldHeight;
+ pScreen->mmWidth = oldmmWidth;
+ pScreen->mmHeight = oldmmHeight;
+ scrp->currentMode = currentMode;
+ }
+
+ /*
+ * Make sure the layout is correct
+ */
+ xf86ReconfigureLayout();
+
+ /*
+ * Make sure the whole screen is visible
+ */
+ xf86SetViewport (pScreen, pScreen->width, pScreen->height);
+ xf86SetViewport (pScreen, 0, 0);
+ if (pRoot)
+ (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+ return ret;
+}
+
+Bool
+xf86RandR12SetConfig (ScreenPtr pScreen,
+ Rotation rotation,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ DisplayModePtr mode;
+ int pos[MAXDEVICES][2];
+ Bool useVirtual = FALSE;
+ int maxX = 0, maxY = 0;
+ Rotation oldRotation = randrp->rotation;
+ DeviceIntPtr dev;
+ Bool view_adjusted = FALSE;
+
+ randrp->rotation = rotation;
+
+ if (randrp->virtualX == -1 || randrp->virtualY == -1)
+ {
+ randrp->virtualX = scrp->virtualX;
+ randrp->virtualY = scrp->virtualY;
+ }
+
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (!IsMaster(dev) && !IsFloating(dev))
+ continue;
+
+ miPointerGetPosition(dev, &pos[dev->id][0], &pos[dev->id][1]);
+ }
+
+ for (mode = scrp->modes; ; mode = mode->next)
+ {
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ if (maxX < mode->HDisplay)
+ maxX = mode->HDisplay;
+ if (maxY < mode->VDisplay)
+ maxY = mode->VDisplay;
+ }
+ if (mode->HDisplay == pSize->width &&
+ mode->VDisplay == pSize->height &&
+ (rate == 0 || xf86RandR12ModeRefresh (mode) == rate))
+ break;
+ if (mode->next == scrp->modes)
+ {
+ if (pSize->width == randrp->virtualX &&
+ pSize->height == randrp->virtualY)
+ {
+ mode = scrp->modes;
+ useVirtual = TRUE;
+ break;
+ }
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ randrp->maxX = maxX;
+ randrp->maxY = maxY;
+ }
+ return FALSE;
+ }
+ }
+
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ randrp->maxX = maxX;
+ randrp->maxY = maxY;
+ }
+
+ if (!xf86RandR12SetMode (pScreen, mode, useVirtual, pSize->mmWidth,
+ pSize->mmHeight)) {
+ randrp->rotation = oldRotation;
+ return FALSE;
+ }
+
+ /*
+ * Move the cursor back where it belongs; SwitchMode repositions it
+ * FIXME: duplicated code, see modes/xf86RandR12.c
+ */
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (!IsMaster(dev) && !IsFloating(dev))
+ continue;
+
+ if (pScreen == miPointerGetScreen(dev)) {
+ int px = pos[dev->id][0];
+ int py = pos[dev->id][1];
+
+ px = (px >= pScreen->width ? (pScreen->width - 1) : px);
+ py = (py >= pScreen->height ? (pScreen->height - 1) : py);
+
+ /* Setting the viewpoint makes only sense on one device */
+ if (!view_adjusted && IsMaster(dev)) {
+ xf86SetViewport(pScreen, px, py);
+ view_adjusted = TRUE;
+ }
+
+ (*pScreen->SetCursorPosition) (dev, pScreen, px, py, FALSE);
+ }
+ }
+
+ return TRUE;
+}
+
+static Bool
+xf86RandR12ScreenSetSize (ScreenPtr pScreen,
+ CARD16 width,
+ CARD16 height,
+ CARD32 mmWidth,
+ CARD32 mmHeight)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ WindowPtr pRoot = pScreen->root;
+ PixmapPtr pScrnPix;
+ Bool ret = FALSE;
+ int c;
+
+ if (xf86RandR12Key) {
+ if (randrp->virtualX == -1 || randrp->virtualY == -1)
+ {
+ randrp->virtualX = pScrn->virtualX;
+ randrp->virtualY = pScrn->virtualY;
+ }
+ }
+ if (pRoot && pScrn->vtSema)
+ (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
+
+ /* Let the driver update virtualX and virtualY */
+ if (!(*config->funcs->resize)(pScrn, width, height))
+ goto finish;
+
+ ret = TRUE;
+ /* Update panning information */
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 ||
+ crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+ if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1)
+ crtc->panningTotalArea.x2 += width - pScreen->width;
+ if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1)
+ crtc->panningTotalArea.y2 += height - pScreen->height;
+ if (crtc->panningTrackingArea.x2 > crtc->panningTrackingArea.x1)
+ crtc->panningTrackingArea.x2 += width - pScreen->width;
+ if (crtc->panningTrackingArea.y2 > crtc->panningTrackingArea.y1)
+ crtc->panningTrackingArea.y2 += height - pScreen->height;
+ xf86RandR13VerifyPanningArea (crtc, width, height);
+ xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+ }
+ }
+
+ pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
+ pScreen->width = pScrnPix->drawable.width = width;
+ pScreen->height = pScrnPix->drawable.height = height;
+ randrp->mmWidth = pScreen->mmWidth = mmWidth;
+ randrp->mmHeight = pScreen->mmHeight = mmHeight;
+
+ xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
+ xf86SetViewport (pScreen, 0, 0);
+
+finish:
+ if (pRoot && pScrn->vtSema)
+ (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+#if RANDR_12_INTERFACE
+ if (xf86RandR12Key && pScreen->root && ret)
+ RRScreenSizeNotify (pScreen);
+#endif
+ return ret;
+}
+
+Rotation
+xf86RandR12GetRotation(ScreenPtr pScreen)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+
+ return randrp->rotation;
+}
+
+Bool
+xf86RandR12CreateScreenResources (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config;
+ XF86RandRInfoPtr randrp;
+ int c;
+ int width, height;
+ int mmWidth, mmHeight;
+#ifdef PANORAMIX
+ /* XXX disable RandR when using Xinerama */
+ if (!noPanoramiXExtension)
+ return TRUE;
+#endif
+
+ config = XF86_CRTC_CONFIG_PTR(pScrn);
+ randrp = XF86RANDRINFO(pScreen);
+ /*
+ * Compute size of screen
+ */
+ width = 0; height = 0;
+ for (c = 0; c < config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = config->crtc[c];
+ int crtc_width = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
+ int crtc_height = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
+
+ if (crtc->enabled) {
+ if (crtc_width > width)
+ width = crtc_width;
+ if (crtc_height > height)
+ height = crtc_height;
+ if (crtc->panningTotalArea.x2 > width)
+ width = crtc->panningTotalArea.x2;
+ if (crtc->panningTotalArea.y2 > height)
+ height = crtc->panningTotalArea.y2;
+ }
+ }
+
+ if (width && height)
+ {
+ /*
+ * Compute physical size of screen
+ */
+ if (monitorResolution)
+ {
+ mmWidth = width * 25.4 / monitorResolution;
+ mmHeight = height * 25.4 / monitorResolution;
+ }
+ else
+ {
+ xf86OutputPtr output = xf86CompatOutput(pScrn);
+
+ if (output &&
+ output->conf_monitor &&
+ (output->conf_monitor->mon_width > 0 &&
+ output->conf_monitor->mon_height > 0))
+ {
+ /*
+ * Prefer user configured DisplaySize
+ */
+ mmWidth = output->conf_monitor->mon_width;
+ mmHeight = output->conf_monitor->mon_height;
+ }
+ else
+ {
+ /*
+ * Otherwise, just set the screen to DEFAULT_DPI
+ */
+ mmWidth = width * 25.4 / DEFAULT_DPI;
+ mmHeight = height * 25.4 / DEFAULT_DPI;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Setting screen physical size to %d x %d\n",
+ mmWidth, mmHeight);
+ /*
+ * This is the initial setting of the screen size.
+ * We have to pre-set it here, otherwise panning would be adapted
+ * to the new screen size.
+ */
+ pScreen->width = width;
+ pScreen->height = height;
+ xf86RandR12ScreenSetSize (pScreen,
+ width,
+ height,
+ mmWidth,
+ mmHeight);
+ }
+
+ if (xf86RandR12Key == NULL)
+ return TRUE;
+
+ if (randrp->virtualX == -1 || randrp->virtualY == -1)
+ {
+ randrp->virtualX = pScrn->virtualX;
+ randrp->virtualY = pScrn->virtualY;
+ }
+ xf86CrtcSetScreenSubpixelOrder (pScreen);
+#if RANDR_12_INTERFACE
+ if (xf86RandR12CreateScreenResources12 (pScreen))
+ return TRUE;
+#endif
+ return TRUE;
+}
+
+
+Bool
+xf86RandR12Init (ScreenPtr pScreen)
+{
+ rrScrPrivPtr rp;
+ XF86RandRInfoPtr randrp;
+
+#ifdef PANORAMIX
+ /* XXX disable RandR when using Xinerama */
+ if (!noPanoramiXExtension)
+ {
+ if (xf86NumScreens == 1)
+ noPanoramiXExtension = TRUE;
+ else
+ return TRUE;
+ }
+#endif
+
+ if (xf86RandR12Generation != serverGeneration)
+ xf86RandR12Generation = serverGeneration;
+
+ xf86RandR12Key = &xf86RandR12KeyRec;
+ if (!dixRegisterPrivateKey(&xf86RandR12KeyRec, PRIVATE_SCREEN, 0))
+ return FALSE;
+
+ randrp = malloc(sizeof (XF86RandRInfoRec));
+ if (!randrp)
+ return FALSE;
+
+ if (!RRScreenInit(pScreen))
+ {
+ free(randrp);
+ return FALSE;
+ }
+ rp = rrGetScrPriv(pScreen);
+ rp->rrGetInfo = xf86RandR12GetInfo;
+ rp->rrSetConfig = xf86RandR12SetConfig;
+
+ randrp->virtualX = -1;
+ randrp->virtualY = -1;
+ randrp->mmWidth = pScreen->mmWidth;
+ randrp->mmHeight = pScreen->mmHeight;
+
+ randrp->rotation = RR_Rotate_0; /* initial rotated mode */
+
+ randrp->supported_rotations = RR_Rotate_0;
+
+ randrp->maxX = randrp->maxY = 0;
+
+ dixSetPrivate(&pScreen->devPrivates, xf86RandR12Key, randrp);
+
+#if RANDR_12_INTERFACE
+ if (!xf86RandR12Init12 (pScreen))
+ return FALSE;
+#endif
+ return TRUE;
+}
+
+void
+xf86RandR12CloseScreen (ScreenPtr pScreen)
+{
+ XF86RandRInfoPtr randrp;
+
+ if (xf86RandR12Key == NULL)
+ return;
+
+ randrp = XF86RANDRINFO(pScreen);
+#if RANDR_12_INTERFACE
+ xf86Screens[pScreen->myNum]->EnterVT = randrp->orig_EnterVT;
+#endif
+
+ free(randrp);
+}
+
+void
+xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
+{
+ XF86RandRInfoPtr randrp;
+#if RANDR_12_INTERFACE
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ int c;
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+#endif
+
+ if (xf86RandR12Key == NULL)
+ return;
+
+ randrp = XF86RANDRINFO(pScreen);
+#if RANDR_12_INTERFACE
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ RRCrtcSetRotations (crtc->randr_crtc, rotations);
+ }
+#endif
+ randrp->supported_rotations = rotations;
+}
+
+void
+xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms)
+{
+ XF86RandRInfoPtr randrp;
+#if RANDR_13_INTERFACE
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ int c;
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+#endif
+
+ if (xf86RandR12Key == NULL)
+ return;
+
+ randrp = XF86RANDRINFO(pScreen);
+#if RANDR_13_INTERFACE
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ RRCrtcSetTransformSupport (crtc->randr_crtc, transforms);
+ }
+#endif
+}
+
+void
+xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
+{
+ ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+
+ if (xf86RandR12Generation != serverGeneration ||
+ XF86RANDRINFO(pScreen)->virtualX == -1)
+ {
+ *x = pScrn->virtualX;
+ *y = pScrn->virtualY;
+ } else {
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+
+ *x = randrp->virtualX;
+ *y = randrp->virtualY;
+ }
+}
+
+#if RANDR_12_INTERFACE
+
+#define FLAG_BITS (RR_HSyncPositive | \
+ RR_HSyncNegative | \
+ RR_VSyncPositive | \
+ RR_VSyncNegative | \
+ RR_Interlace | \
+ RR_DoubleScan | \
+ RR_CSync | \
+ RR_CSyncPositive | \
+ RR_CSyncNegative | \
+ RR_HSkewPresent | \
+ RR_BCast | \
+ RR_PixelMultiplex | \
+ RR_DoubleClock | \
+ RR_ClockDivideBy2)
+
+static Bool
+xf86RandRModeMatches (RRModePtr randr_mode,
+ DisplayModePtr mode)
+{
+#if 0
+ if (match_name)
+ {
+ /* check for same name */
+ int len = strlen (mode->name);
+ if (randr_mode->mode.nameLength != len) return FALSE;
+ if (memcmp (randr_mode->name, mode->name, len) != 0) return FALSE;
+ }
+#endif
+
+ /* check for same timings */
+ if (randr_mode->mode.dotClock / 1000 != mode->Clock) return FALSE;
+ if (randr_mode->mode.width != mode->HDisplay) return FALSE;
+ if (randr_mode->mode.hSyncStart != mode->HSyncStart) return FALSE;
+ if (randr_mode->mode.hSyncEnd != mode->HSyncEnd) return FALSE;
+ if (randr_mode->mode.hTotal != mode->HTotal) return FALSE;
+ if (randr_mode->mode.hSkew != mode->HSkew) return FALSE;
+ if (randr_mode->mode.height != mode->VDisplay) return FALSE;
+ if (randr_mode->mode.vSyncStart != mode->VSyncStart) return FALSE;
+ if (randr_mode->mode.vSyncEnd != mode->VSyncEnd) return FALSE;
+ if (randr_mode->mode.vTotal != mode->VTotal) return FALSE;
+
+ /* check for same flags (using only the XF86 valid flag bits) */
+ if ((randr_mode->mode.modeFlags & FLAG_BITS) != (mode->Flags & FLAG_BITS))
+ return FALSE;
+
+ /* everything matches */
+ return TRUE;
+}
+
+static Bool
+xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
+{
+ ScreenPtr pScreen = randr_crtc->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ RRModePtr randr_mode = NULL;
+ int x;
+ int y;
+ Rotation rotation;
+ int numOutputs;
+ RROutputPtr *randr_outputs;
+ RROutputPtr randr_output;
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+ xf86OutputPtr output;
+ int i, j;
+ DisplayModePtr mode = &crtc->mode;
+ Bool ret;
+
+ randr_outputs = malloc(config->num_output * sizeof (RROutputPtr));
+ if (!randr_outputs)
+ return FALSE;
+ x = crtc->x;
+ y = crtc->y;
+ rotation = crtc->rotation;
+ numOutputs = 0;
+ randr_mode = NULL;
+ for (i = 0; i < config->num_output; i++)
+ {
+ output = config->output[i];
+ if (output->crtc == crtc)
+ {
+ randr_output = output->randr_output;
+ randr_outputs[numOutputs++] = randr_output;
+ /*
+ * We make copies of modes, so pointer equality
+ * isn't sufficient
+ */
+ for (j = 0; j < randr_output->numModes + randr_output->numUserModes; j++)
+ {
+ RRModePtr m = (j < randr_output->numModes ?
+ randr_output->modes[j] :
+ randr_output->userModes[j-randr_output->numModes]);
+
+ if (xf86RandRModeMatches (m, mode))
+ {
+ randr_mode = m;
+ break;
+ }
+ }
+ }
+ }
+ ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
+ rotation,
+ crtc->transformPresent ? &crtc->transform : NULL,
+ numOutputs, randr_outputs);
+ free(randr_outputs);
+ return ret;
+}
+
+/*
+ * Convert a RandR mode to a DisplayMode
+ */
+static void
+xf86RandRModeConvert (ScrnInfoPtr scrn,
+ RRModePtr randr_mode,
+ DisplayModePtr mode)
+{
+ memset(mode, 0, sizeof(DisplayModeRec));
+ mode->status = MODE_OK;
+
+ mode->Clock = randr_mode->mode.dotClock / 1000;
+
+ mode->HDisplay = randr_mode->mode.width;
+ mode->HSyncStart = randr_mode->mode.hSyncStart;
+ mode->HSyncEnd = randr_mode->mode.hSyncEnd;
+ mode->HTotal = randr_mode->mode.hTotal;
+ mode->HSkew = randr_mode->mode.hSkew;
+
+ mode->VDisplay = randr_mode->mode.height;
+ mode->VSyncStart = randr_mode->mode.vSyncStart;
+ mode->VSyncEnd = randr_mode->mode.vSyncEnd;
+ mode->VTotal = randr_mode->mode.vTotal;
+ mode->VScan = 0;
+
+ mode->Flags = randr_mode->mode.modeFlags & FLAG_BITS;
+
+ xf86SetModeCrtc (mode, scrn->adjustFlags);
+}
+
+static Bool
+xf86RandR12CrtcSet (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc,
+ RRModePtr randr_mode,
+ int x,
+ int y,
+ Rotation rotation,
+ int num_randr_outputs,
+ RROutputPtr *randr_outputs)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+ RRTransformPtr transform;
+ Bool changed = FALSE;
+ int o, ro;
+ xf86CrtcPtr *save_crtcs;
+ Bool save_enabled = crtc->enabled;
+
+ if (!crtc->scrn->vtSema)
+ return FALSE;
+
+ save_crtcs = malloc(config->num_output * sizeof (xf86CrtcPtr));
+ if ((randr_mode != NULL) != crtc->enabled)
+ changed = TRUE;
+ else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode))
+ changed = TRUE;
+
+ if (rotation != crtc->rotation)
+ changed = TRUE;
+
+ transform = RRCrtcGetTransform (randr_crtc);
+ if ((transform != NULL) != crtc->transformPresent)
+ changed = TRUE;
+ else if (transform && memcmp (&transform->transform, &crtc->transform.transform,
+ sizeof (transform->transform)) != 0)
+ changed = TRUE;
+
+ if (x != crtc->x || y != crtc->y)
+ changed = TRUE;
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+ xf86CrtcPtr new_crtc;
+
+ save_crtcs[o] = output->crtc;
+
+ if (output->crtc == crtc)
+ new_crtc = NULL;
+ else
+ new_crtc = output->crtc;
+ for (ro = 0; ro < num_randr_outputs; ro++)
+ if (output->randr_output == randr_outputs[ro])
+ {
+ new_crtc = crtc;
+ break;
+ }
+ if (new_crtc != output->crtc)
+ {
+ changed = TRUE;
+ output->crtc = new_crtc;
+ }
+ }
+ for (ro = 0; ro < num_randr_outputs; ro++)
+ if (randr_outputs[ro]->pendingProperties)
+ changed = TRUE;
+
+ /* XXX need device-independent mode setting code through an API */
+ if (changed)
+ {
+ crtc->enabled = randr_mode != NULL;
+
+ if (randr_mode)
+ {
+ DisplayModeRec mode;
+ RRTransformPtr transform = RRCrtcGetTransform (randr_crtc);
+
+ xf86RandRModeConvert (pScrn, randr_mode, &mode);
+ if (!xf86CrtcSetModeTransform (crtc, &mode, rotation, transform, x, y))
+ {
+ crtc->enabled = save_enabled;
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+ output->crtc = save_crtcs[o];
+ }
+ free(save_crtcs);
+ return FALSE;
+ }
+ xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height);
+ xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+ /*
+ * Save the last successful setting for EnterVT
+ */
+ crtc->desiredMode = mode;
+ crtc->desiredRotation = rotation;
+ if (transform) {
+ crtc->desiredTransform = *transform;
+ crtc->desiredTransformPresent = TRUE;
+ } else
+ crtc->desiredTransformPresent = FALSE;
+
+ crtc->desiredX = x;
+ crtc->desiredY = y;
+ }
+ xf86DisableUnusedFunctions (pScrn);
+ }
+ free(save_crtcs);
+ return xf86RandR12CrtcNotify (randr_crtc);
+}
+
+static Bool
+xf86RandR12CrtcSetGamma (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc)
+{
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+
+ if (crtc->funcs->gamma_set == NULL)
+ return FALSE;
+
+ if (!crtc->scrn->vtSema)
+ return TRUE;
+
+ /* Realloc local gamma if needed. */
+ if (randr_crtc->gammaSize != crtc->gamma_size) {
+ CARD16 *tmp_ptr;
+ tmp_ptr = realloc(crtc->gamma_red, 3 * crtc->gamma_size * sizeof (CARD16));
+ if (!tmp_ptr)
+ return FALSE;
+ crtc->gamma_red = tmp_ptr;
+ crtc->gamma_green = crtc->gamma_red + crtc->gamma_size;
+ crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size;
+ }
+
+ crtc->gamma_size = randr_crtc->gammaSize;
+ memcpy (crtc->gamma_red, randr_crtc->gammaRed, crtc->gamma_size * sizeof (CARD16));
+ memcpy (crtc->gamma_green, randr_crtc->gammaGreen, crtc->gamma_size * sizeof (CARD16));
+ memcpy (crtc->gamma_blue, randr_crtc->gammaBlue, crtc->gamma_size * sizeof (CARD16));
+
+ /* Only set it when the crtc is actually running.
+ * Otherwise it will be set when it's activated.
+ */
+ if (crtc->active)
+ crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
+ crtc->gamma_blue, crtc->gamma_size);
+
+ return TRUE;
+}
+
+static Bool
+xf86RandR12CrtcGetGamma (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc)
+{
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+
+ if (!crtc->gamma_size)
+ return FALSE;
+
+ if (!crtc->gamma_red || !crtc->gamma_green || !crtc->gamma_blue)
+ return FALSE;
+
+ /* Realloc randr gamma if needed. */
+ if (randr_crtc->gammaSize != crtc->gamma_size) {
+ CARD16 *tmp_ptr;
+ tmp_ptr = realloc(randr_crtc->gammaRed, 3 * crtc->gamma_size * sizeof (CARD16));
+ if (!tmp_ptr)
+ return FALSE;
+ randr_crtc->gammaRed = tmp_ptr;
+ randr_crtc->gammaGreen = randr_crtc->gammaRed + crtc->gamma_size;
+ randr_crtc->gammaBlue = randr_crtc->gammaGreen + crtc->gamma_size;
+ }
+ randr_crtc->gammaSize = crtc->gamma_size;
+ memcpy (randr_crtc->gammaRed, crtc->gamma_red, crtc->gamma_size * sizeof (CARD16));
+ memcpy (randr_crtc->gammaGreen, crtc->gamma_green, crtc->gamma_size * sizeof (CARD16));
+ memcpy (randr_crtc->gammaBlue, crtc->gamma_blue, crtc->gamma_size * sizeof (CARD16));
+
+ return TRUE;
+}
+
+static Bool
+xf86RandR12OutputSetProperty (ScreenPtr pScreen,
+ RROutputPtr randr_output,
+ Atom property,
+ RRPropertyValuePtr value)
+{
+ xf86OutputPtr output = randr_output->devPrivate;
+
+ /* If we don't have any property handler, then we don't care what the
+ * user is setting properties to.
+ */
+ if (output->funcs->set_property == NULL)
+ return TRUE;
+
+ /*
+ * This function gets called even when vtSema is FALSE, as
+ * drivers will need to remember the correct value to apply
+ * when the VT switch occurs
+ */
+ return output->funcs->set_property(output, property, value);
+}
+
+static Bool
+xf86RandR13OutputGetProperty (ScreenPtr pScreen,
+ RROutputPtr randr_output,
+ Atom property)
+{
+ xf86OutputPtr output = randr_output->devPrivate;
+
+ if (output->funcs->get_property == NULL)
+ return TRUE;
+
+ /* Should be safe even w/o vtSema */
+ return output->funcs->get_property(output, property);
+}
+
+static Bool
+xf86RandR12OutputValidateMode (ScreenPtr pScreen,
+ RROutputPtr randr_output,
+ RRModePtr randr_mode)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86OutputPtr output = randr_output->devPrivate;
+ DisplayModeRec mode;
+
+ xf86RandRModeConvert (pScrn, randr_mode, &mode);
+ /*
+ * This function may be called when vtSema is FALSE, so
+ * the underlying function must either avoid touching the hardware
+ * or return FALSE when vtSema is FALSE
+ */
+ if (output->funcs->mode_valid (output, &mode) != MODE_OK)
+ return FALSE;
+ return TRUE;
+}
+
+static void
+xf86RandR12ModeDestroy (ScreenPtr pScreen, RRModePtr randr_mode)
+{
+}
+
+/**
+ * Given a list of xf86 modes and a RandR Output object, construct
+ * RandR modes and assign them to the output
+ */
+static Bool
+xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
+{
+ DisplayModePtr mode;
+ RRModePtr *rrmodes = NULL;
+ int nmode = 0;
+ int npreferred = 0;
+ Bool ret = TRUE;
+ int pref;
+
+ for (mode = modes; mode; mode = mode->next)
+ nmode++;
+
+ if (nmode) {
+ rrmodes = malloc(nmode * sizeof (RRModePtr));
+
+ if (!rrmodes)
+ return FALSE;
+ nmode = 0;
+
+ for (pref = 1; pref >= 0; pref--) {
+ for (mode = modes; mode; mode = mode->next) {
+ if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) {
+ xRRModeInfo modeInfo;
+ RRModePtr rrmode;
+
+ modeInfo.nameLength = strlen (mode->name);
+ modeInfo.width = mode->HDisplay;
+ modeInfo.dotClock = mode->Clock * 1000;
+ modeInfo.hSyncStart = mode->HSyncStart;
+ modeInfo.hSyncEnd = mode->HSyncEnd;
+ modeInfo.hTotal = mode->HTotal;
+ modeInfo.hSkew = mode->HSkew;
+
+ modeInfo.height = mode->VDisplay;
+ modeInfo.vSyncStart = mode->VSyncStart;
+ modeInfo.vSyncEnd = mode->VSyncEnd;
+ modeInfo.vTotal = mode->VTotal;
+ modeInfo.modeFlags = mode->Flags;
+
+ rrmode = RRModeGet (&modeInfo, mode->name);
+ if (rrmode) {
+ rrmodes[nmode++] = rrmode;
+ npreferred += pref;
+ }
+ }
+ }
+ }
+ }
+
+ ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred);
+ free(rrmodes);
+ return ret;
+}
+
+/*
+ * Mirror the current mode configuration to RandR
+ */
+static Bool
+xf86RandR12SetInfo12 (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ RROutputPtr *clones;
+ RRCrtcPtr *crtcs;
+ int ncrtc;
+ int o, c, l;
+ RRCrtcPtr randr_crtc;
+ int nclone;
+
+ clones = malloc(config->num_output * sizeof (RROutputPtr));
+ crtcs = malloc(config->num_crtc * sizeof (RRCrtcPtr));
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+
+ ncrtc = 0;
+ for (c = 0; c < config->num_crtc; c++)
+ if (output->possible_crtcs & (1 << c))
+ crtcs[ncrtc++] = config->crtc[c]->randr_crtc;
+
+ if (output->crtc)
+ randr_crtc = output->crtc->randr_crtc;
+ else
+ randr_crtc = NULL;
+
+ if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc))
+ {
+ free(crtcs);
+ free(clones);
+ return FALSE;
+ }
+
+ RROutputSetPhysicalSize(output->randr_output,
+ output->mm_width,
+ output->mm_height);
+ xf86RROutputSetModes (output->randr_output, output->probed_modes);
+
+ switch (output->status) {
+ case XF86OutputStatusConnected:
+ RROutputSetConnection (output->randr_output, RR_Connected);
+ break;
+ case XF86OutputStatusDisconnected:
+ RROutputSetConnection (output->randr_output, RR_Disconnected);
+ break;
+ case XF86OutputStatusUnknown:
+ RROutputSetConnection (output->randr_output, RR_UnknownConnection);
+ break;
+ }
+
+ RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order);
+
+ /*
+ * Valid clones
+ */
+ nclone = 0;
+ for (l = 0; l < config->num_output; l++)
+ {
+ xf86OutputPtr clone = config->output[l];
+
+ if (l != o && (output->possible_clones & (1 << l)))
+ clones[nclone++] = clone->randr_output;
+ }
+ if (!RROutputSetClones (output->randr_output, clones, nclone))
+ {
+ free(crtcs);
+ free(clones);
+ return FALSE;
+ }
+ }
+ free(crtcs);
+ free(clones);
+ return TRUE;
+}
+
+
+
+/*
+ * Query the hardware for the current state, then mirror
+ * that to RandR
+ */
+static Bool
+xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if (!pScrn->vtSema)
+ return TRUE;
+ xf86ProbeOutputModes (pScrn, 0, 0);
+ xf86SetScrnInfoModes (pScrn);
+ return xf86RandR12SetInfo12 (pScreen);
+}
+
+static Bool
+xf86RandR12CreateObjects12 (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int c;
+ int o;
+
+ if (!RRInit ())
+ return FALSE;
+
+ /*
+ * Configure crtcs
+ */
+ for (c = 0; c < config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ crtc->randr_crtc = RRCrtcCreate (pScreen, crtc);
+ RRCrtcGammaSetSize (crtc->randr_crtc, 256);
+ }
+ /*
+ * Configure outputs
+ */
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+
+ output->randr_output = RROutputCreate (pScreen, output->name,
+ strlen (output->name),
+ output);
+
+ if (output->funcs->create_resources != NULL)
+ output->funcs->create_resources(output);
+ RRPostPendingProperties (output->randr_output);
+ }
+ return TRUE;
+}
+
+static Bool
+xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
+{
+ int c;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+ if (xf86RandR12Key == NULL)
+ return TRUE;
+
+ for (c = 0; c < config->num_crtc; c++)
+ xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
+
+ RRScreenSetSizeRange (pScreen, config->minWidth, config->minHeight,
+ config->maxWidth, config->maxHeight);
+ return TRUE;
+}
+
+/*
+ * Something happened within the screen configuration due
+ * to DGA, VidMode or hot key. Tell RandR
+ */
+
+void
+xf86RandR12TellChanged (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int c;
+
+ if (xf86RandR12Key == NULL)
+ return;
+
+ xf86RandR12SetInfo12 (pScreen);
+ for (c = 0; c < config->num_crtc; c++)
+ xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
+
+ RRTellChanged (pScreen);
+}
+
+static void
+xf86RandR12PointerMoved (int scrnIndex, int x, int y)
+{
+ ScreenPtr pScreen = screenInfo.screens[scrnIndex];
+ ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ int c;
+
+ randrp->pointerX = x;
+ randrp->pointerY = y;
+ for (c = 0; c < config->num_crtc; c++)
+ xf86RandR13Pan (config->crtc[c], x, y);
+}
+
+static Bool
+xf86RandR13GetPanning (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border)
+{
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+
+ if (crtc->version < 2)
+ return FALSE;
+ if (totalArea)
+ memcpy (totalArea, &crtc->panningTotalArea, sizeof(BoxRec));
+ if (trackingArea)
+ memcpy (trackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
+ if (border)
+ memcpy (border, crtc->panningBorder, 4*sizeof(INT16));
+
+ return TRUE;
+}
+
+static Bool
+xf86RandR13SetPanning (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+ BoxRec oldTotalArea;
+ BoxRec oldTrackingArea;
+ INT16 oldBorder[4];
+
+
+ if (crtc->version < 2)
+ return FALSE;
+
+ memcpy (&oldTotalArea, &crtc->panningTotalArea, sizeof(BoxRec));
+ memcpy (&oldTrackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
+ memcpy (oldBorder, crtc->panningBorder, 4*sizeof(INT16));
+
+ if (totalArea)
+ memcpy (&crtc->panningTotalArea, totalArea, sizeof(BoxRec));
+ if (trackingArea)
+ memcpy (&crtc->panningTrackingArea, trackingArea, sizeof(BoxRec));
+ if (border)
+ memcpy (crtc->panningBorder, border, 4*sizeof(INT16));
+
+ if (xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height)) {
+ xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+ return TRUE;
+ } else {
+ /* Restore old settings */
+ memcpy (&crtc->panningTotalArea, &oldTotalArea, sizeof(BoxRec));
+ memcpy (&crtc->panningTrackingArea, &oldTrackingArea, sizeof(BoxRec));
+ memcpy (crtc->panningBorder, oldBorder, 4*sizeof(INT16));
+ return FALSE;
+ }
+}
+
+/*
+ * Compatibility with XF86VidMode's gamma changer. This necessarily clobbers
+ * any per-crtc setup. You asked for it...
+ */
+
+static void
+gamma_to_ramp(float gamma, CARD16 *ramp, int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (gamma == 1.0)
+ ramp[i] = i << 8;
+ else
+ ramp[i] = (CARD16)(pow((double)i / (double)(size - 1), 1. / gamma)
+ * (double)(size - 1) * 256);
+ }
+}
+
+static int
+xf86RandR12ChangeGamma(int scrnIndex, Gamma gamma)
+{
+ CARD16 *points, *red, *green, *blue;
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
+ int size;
+
+ if (!crtc)
+ return Success;
+
+ size = max(0, crtc->gammaSize);
+ if (!size)
+ return Success;
+
+ points = calloc(size, 3 * sizeof(CARD16));
+ if (!points)
+ return BadAlloc;
+
+ red = points;
+ green = points + size;
+ blue = points + 2 * size;
+
+ gamma_to_ramp(gamma.red, red, size);
+ gamma_to_ramp(gamma.green, green, size);
+ gamma_to_ramp(gamma.blue, blue, size);
+ RRCrtcGammaSet(crtc, red, green, blue);
+
+ free(points);
+
+ pScrn->gamma = gamma;
+
+ return Success;
+}
+
+static Bool
+xf86RandR12EnterVT (int screen_index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[screen_index];
+ ScrnInfoPtr pScrn = xf86Screens[screen_index];
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ rrScrPrivPtr rp = rrGetScrPriv(pScreen);
+ Bool ret;
+ int i;
+
+ if (randrp->orig_EnterVT) {
+ pScrn->EnterVT = randrp->orig_EnterVT;
+ ret = pScrn->EnterVT (screen_index, flags);
+ randrp->orig_EnterVT = pScrn->EnterVT;
+ pScrn->EnterVT = xf86RandR12EnterVT;
+ if (!ret)
+ return FALSE;
+ }
+
+ /* reload gamma */
+ for (i = 0; i < rp->numCrtcs; i++)
+ xf86RandR12CrtcSetGamma(pScreen, rp->crtcs[i]);
+
+ return RRGetInfo (pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */
+}
+
+static Bool
+xf86RandR12Init12 (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ rrScrPrivPtr rp = rrGetScrPriv(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ int i;
+
+ rp->rrGetInfo = xf86RandR12GetInfo12;
+ rp->rrScreenSetSize = xf86RandR12ScreenSetSize;
+ rp->rrCrtcSet = xf86RandR12CrtcSet;
+ rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
+ rp->rrCrtcGetGamma = xf86RandR12CrtcGetGamma;
+ rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
+ rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
+#if RANDR_13_INTERFACE
+ rp->rrOutputGetProperty = xf86RandR13OutputGetProperty;
+ rp->rrGetPanning = xf86RandR13GetPanning;
+ rp->rrSetPanning = xf86RandR13SetPanning;
+#endif
+ rp->rrModeDestroy = xf86RandR12ModeDestroy;
+ rp->rrSetConfig = NULL;
+ pScrn->PointerMoved = xf86RandR12PointerMoved;
+ pScrn->ChangeGamma = xf86RandR12ChangeGamma;
+
+ randrp->orig_EnterVT = pScrn->EnterVT;
+ pScrn->EnterVT = xf86RandR12EnterVT;
+
+ if (!xf86RandR12CreateObjects12 (pScreen))
+ return FALSE;
+
+ /*
+ * Configure output modes
+ */
+ if (!xf86RandR12SetInfo12 (pScreen))
+ return FALSE;
+ for (i = 0; i < rp->numCrtcs; i++) {
+ xf86RandR12CrtcGetGamma(pScreen, rp->crtcs[i]);
+ }
+ return TRUE;
+}
+
+#endif
+
+Bool
+xf86RandR12PreInit (ScrnInfoPtr pScrn)
+{
+ return TRUE;
+}
diff --git a/xorg-server/hw/xfree86/modes/xf86Rotate.c b/xorg-server/hw/xfree86/modes/xf86Rotate.c
index 57c3499ac..655857597 100644
--- a/xorg-server/hw/xfree86/modes/xf86Rotate.c
+++ b/xorg-server/hw/xfree86/modes/xf86Rotate.c
@@ -1,525 +1,525 @@
-/*
- * Copyright © 2006 Keith Packard
- *
- * 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 the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The 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 COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE 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.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#else
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#endif
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include "fb.h"
-#include "windowstr.h"
-#include "xf86Crtc.h"
-#include "xf86Modes.h"
-#include "xf86RandR12.h"
-#include "X11/extensions/render.h"
-#include "X11/extensions/dpmsconst.h"
-#include "X11/Xatom.h"
-
-/* borrowed from composite extension, move to Render and publish? */
-
-static VisualPtr
-compGetWindowVisual (WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- VisualID vid = wVisual (pWin);
- int i;
-
- for (i = 0; i < pScreen->numVisuals; i++)
- if (pScreen->visuals[i].vid == vid)
- return &pScreen->visuals[i];
- return 0;
-}
-
-static PictFormatPtr
-compWindowFormat (WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- return PictureMatchVisual (pScreen, pWin->drawable.depth,
- compGetWindowVisual (pWin));
-}
-
-#define F(x) IntToxFixed(x)
-
-#define toF(x) ((float) (x) / 65536.0f)
-
-static void
-xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
-{
- ScrnInfoPtr scrn = crtc->scrn;
- ScreenPtr screen = scrn->pScreen;
- WindowPtr root = screen->root;
- PixmapPtr dst_pixmap = crtc->rotatedPixmap;
- PictFormatPtr format = compWindowFormat (screen->root);
- int error;
- PicturePtr src, dst;
- int n = RegionNumRects(region);
- BoxPtr b = RegionRects(region);
- XID include_inferiors = IncludeInferiors;
-
- src = CreatePicture (None,
- &root->drawable,
- format,
- CPSubwindowMode,
- &include_inferiors,
- serverClient,
- &error);
- if (!src)
- return;
-
- dst = CreatePicture (None,
- &dst_pixmap->drawable,
- format,
- 0L,
- NULL,
- serverClient,
- &error);
- if (!dst)
- return;
-
- error = SetPictureTransform (src, &crtc->crtc_to_framebuffer);
- if (error)
- return;
- if (crtc->transform_in_use && crtc->filter)
- SetPicturePictFilter (src, crtc->filter,
- crtc->params, crtc->nparams);
-
- if (crtc->shadowClear)
- {
- CompositePicture (PictOpSrc,
- src, NULL, dst,
- 0, 0, 0, 0, 0, 0,
- crtc->mode.HDisplay, crtc->mode.VDisplay);
- crtc->shadowClear = FALSE;
- }
- else
- {
- while (n--)
- {
- BoxRec dst_box;
-
- dst_box = *b;
- dst_box.x1 -= crtc->filter_width >> 1;
- dst_box.x2 += crtc->filter_width >> 1;
- dst_box.y1 -= crtc->filter_height >> 1;
- dst_box.y2 += crtc->filter_height >> 1;
- pixman_f_transform_bounds (&crtc->f_framebuffer_to_crtc, &dst_box);
- CompositePicture (PictOpSrc,
- src, NULL, dst,
- dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1,
- dst_box.x2 - dst_box.x1,
- dst_box.y2 - dst_box.y1);
- b++;
- }
- }
- FreePicture (src, None);
- FreePicture (dst, None);
-}
-
-static void
-xf86CrtcDamageShadow (xf86CrtcPtr crtc)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- BoxRec damage_box;
- RegionRec damage_region;
- ScreenPtr pScreen = pScrn->pScreen;
-
- damage_box.x1 = 0;
- damage_box.x2 = crtc->mode.HDisplay;
- damage_box.y1 = 0;
- damage_box.y2 = crtc->mode.VDisplay;
- if (!pixman_transform_bounds (&crtc->crtc_to_framebuffer, &damage_box))
- {
- damage_box.x1 = 0;
- damage_box.y1 = 0;
- damage_box.x2 = pScreen->width;
- damage_box.y2 = pScreen->height;
- }
- if (damage_box.x1 < 0) damage_box.x1 = 0;
- if (damage_box.y1 < 0) damage_box.y1 = 0;
- if (damage_box.x2 > pScreen->width) damage_box.x2 = pScreen->width;
- if (damage_box.y2 > pScreen->height) damage_box.y2 = pScreen->height;
- RegionInit(&damage_region, &damage_box, 1);
- DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
- &damage_region);
- RegionUninit(&damage_region);
- crtc->shadowClear = TRUE;
-}
-
-static void
-xf86RotatePrepare (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
-
- for (c = 0; c < xf86_config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = xf86_config->crtc[c];
-
- if (crtc->rotatedData && !crtc->rotatedPixmap)
- {
- crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
- crtc->rotatedData,
- crtc->mode.HDisplay,
- crtc->mode.VDisplay);
- if (!xf86_config->rotation_damage_registered)
- {
- /* Hook damage to screen pixmap */
- DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
- xf86_config->rotation_damage);
- xf86_config->rotation_damage_registered = TRUE;
- EnableLimitedSchedulingLatency();
- }
-
- xf86CrtcDamageShadow (crtc);
- }
- }
-}
-
-static Bool
-xf86RotateRedisplay(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- DamagePtr damage = xf86_config->rotation_damage;
- RegionPtr region;
-
- if (!damage)
- return FALSE;
- xf86RotatePrepare (pScreen);
- region = DamageRegion(damage);
- if (RegionNotEmpty(region))
- {
- int c;
- SourceValidateProcPtr SourceValidate;
-
- /*
- * SourceValidate is used by the software cursor code
- * to pull the cursor off of the screen when reading
- * bits from the frame buffer. Bypassing this function
- * leaves the software cursor in place
- */
- SourceValidate = pScreen->SourceValidate;
- pScreen->SourceValidate = NULL;
-
- for (c = 0; c < xf86_config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = xf86_config->crtc[c];
-
- if (crtc->transform_in_use && crtc->enabled)
- {
- RegionRec crtc_damage;
-
- /* compute portion of damage that overlaps crtc */
- RegionInit(&crtc_damage, &crtc->bounds, 1);
- RegionIntersect(&crtc_damage, &crtc_damage, region);
-
- /* update damaged region */
- if (RegionNotEmpty(&crtc_damage))
- xf86RotateCrtcRedisplay (crtc, &crtc_damage);
-
- RegionUninit(&crtc_damage);
- }
- }
- pScreen->SourceValidate = SourceValidate;
- DamageEmpty(damage);
- }
- return TRUE;
-}
-
-static void
-xf86RotateBlockHandler(int screenNum, pointer blockData,
- pointer pTimeout, pointer pReadmask)
-{
- ScreenPtr pScreen = screenInfo.screens[screenNum];
- ScrnInfoPtr pScrn = xf86Screens[screenNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- Bool rotation_active;
-
- rotation_active = xf86RotateRedisplay(pScreen);
- pScreen->BlockHandler = xf86_config->BlockHandler;
- (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
- /* cannot avoid re-wrapping until all wrapping is audited */
- xf86_config->BlockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = xf86RotateBlockHandler;
-}
-
-void
-xf86RotateDestroy (xf86CrtcPtr crtc)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- ScreenPtr pScreen = pScrn->pScreen;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
-
- /* Free memory from rotation */
- if (crtc->rotatedPixmap || crtc->rotatedData)
- {
- crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap, crtc->rotatedData);
- crtc->rotatedPixmap = NULL;
- crtc->rotatedData = NULL;
- }
-
- for (c = 0; c < xf86_config->num_crtc; c++)
- if (xf86_config->crtc[c]->transform_in_use)
- return;
-
- /*
- * Clean up damage structures when no crtcs are rotated
- */
- if (xf86_config->rotation_damage)
- {
- /* Free damage structure */
- if (xf86_config->rotation_damage_registered)
- {
- DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
- xf86_config->rotation_damage);
- xf86_config->rotation_damage_registered = FALSE;
- DisableLimitedSchedulingLatency();
- }
- DamageDestroy (xf86_config->rotation_damage);
- xf86_config->rotation_damage = NULL;
- }
-}
-
-void
-xf86RotateFreeShadow(ScrnInfoPtr pScrn)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
-
- for (c = 0; c < config->num_crtc; c++) {
- xf86CrtcPtr crtc = config->crtc[c];
-
- if (crtc->rotatedPixmap || crtc->rotatedData) {
- crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
- crtc->rotatedData);
- crtc->rotatedPixmap = NULL;
- crtc->rotatedData = NULL;
- }
- }
-}
-
-void
-xf86RotateCloseScreen (ScreenPtr screen)
-{
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- int c;
-
- for (c = 0; c < xf86_config->num_crtc; c++)
- xf86RotateDestroy (xf86_config->crtc[c]);
-}
-
-static Bool
-xf86CrtcFitsScreen (xf86CrtcPtr crtc, struct pict_f_transform *crtc_to_fb)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- BoxRec b;
-
- /* When called before PreInit, the driver is
- * presumably doing load detect
- */
- if (pScrn->virtualX == 0 || pScrn->virtualY == 0)
- return TRUE;
-
- b.x1 = 0;
- b.y1 = 0;
- b.x2 = crtc->mode.HDisplay;
- b.y2 = crtc->mode.VDisplay;
- if (crtc_to_fb)
- pixman_f_transform_bounds (crtc_to_fb, &b);
- else {
- b.x1 += crtc->x;
- b.y1 += crtc->y;
- b.x2 += crtc->x;
- b.y2 += crtc->y;
- }
-
- return (0 <= b.x1 && b.x2 <= pScrn->virtualX &&
- 0 <= b.y1 && b.y2 <= pScrn->virtualY);
-}
-
-Bool
-xf86CrtcRotate (xf86CrtcPtr crtc)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
- ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
- PictTransform crtc_to_fb;
- struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc;
- xFixed *new_params = NULL;
- int new_nparams = 0;
- PictFilterPtr new_filter = NULL;
- int new_width = 0;
- int new_height = 0;
- RRTransformPtr transform = NULL;
- Bool damage = FALSE;
-
- if (crtc->transformPresent)
- transform = &crtc->transform;
-
- if (!RRTransformCompute (crtc->x, crtc->y,
- crtc->mode.HDisplay, crtc->mode.VDisplay,
- crtc->rotation,
- transform,
-
- &crtc_to_fb,
- &f_crtc_to_fb,
- &f_fb_to_crtc) &&
- xf86CrtcFitsScreen (crtc, &f_crtc_to_fb))
- {
- /*
- * If the untranslated transformation is the identity,
- * disable the shadow buffer
- */
- xf86RotateDestroy (crtc);
- crtc->transform_in_use = FALSE;
- free(new_params);
- new_params = NULL;
- new_nparams = 0;
- new_filter = NULL;
- new_width = 0;
- new_height = 0;
- }
- else
- {
- /*
- * these are the size of the shadow pixmap, which
- * matches the mode, not the pre-rotated copy in the
- * frame buffer
- */
- int width = crtc->mode.HDisplay;
- int height = crtc->mode.VDisplay;
- void *shadowData = crtc->rotatedData;
- PixmapPtr shadow = crtc->rotatedPixmap;
- int old_width = shadow ? shadow->drawable.width : 0;
- int old_height = shadow ? shadow->drawable.height : 0;
-
- /* Allocate memory for rotation */
- if (old_width != width || old_height != height)
- {
- if (shadow || shadowData)
- {
- crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
- crtc->rotatedPixmap = NULL;
- crtc->rotatedData = NULL;
- }
- shadowData = crtc->funcs->shadow_allocate (crtc, width, height);
- if (!shadowData)
- goto bail1;
- crtc->rotatedData = shadowData;
- /* shadow will be damaged in xf86RotatePrepare */
- }
- else
- {
- /* mark shadowed area as damaged so it will be repainted */
- damage = TRUE;
- }
-
- if (!xf86_config->rotation_damage)
- {
- /* Create damage structure */
- xf86_config->rotation_damage = DamageCreate (NULL, NULL,
- DamageReportNone,
- TRUE, pScreen, pScreen);
- if (!xf86_config->rotation_damage)
- goto bail2;
-
- /* Wrap block handler */
- if (!xf86_config->BlockHandler) {
- xf86_config->BlockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = xf86RotateBlockHandler;
- }
- }
-#ifdef RANDR_12_INTERFACE
- if (transform)
- {
- if (transform->nparams) {
- new_params = malloc(transform->nparams * sizeof (xFixed));
- if (new_params) {
- memcpy (new_params, transform->params,
- transform->nparams * sizeof (xFixed));
- new_nparams = transform->nparams;
- new_filter = transform->filter;
- }
- } else
- new_filter = transform->filter;
- if (new_filter)
- {
- new_width = new_filter->width;
- new_height = new_filter->height;
- }
- }
-#endif
-
- if (0)
- {
- bail2:
- if (shadow || shadowData)
- {
- crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
- crtc->rotatedPixmap = NULL;
- crtc->rotatedData = NULL;
- }
- bail1:
- if (old_width && old_height)
- crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
- NULL,
- old_width,
- old_height);
- return FALSE;
- }
- crtc->transform_in_use = TRUE;
- }
- crtc->crtc_to_framebuffer = crtc_to_fb;
- crtc->f_crtc_to_framebuffer = f_crtc_to_fb;
- crtc->f_framebuffer_to_crtc = f_fb_to_crtc;
- free(crtc->params);
- crtc->params = new_params;
- crtc->nparams = new_nparams;
- crtc->filter = new_filter;
- crtc->filter_width = new_width;
- crtc->filter_height = new_height;
- crtc->bounds.x1 = 0;
- crtc->bounds.x2 = crtc->mode.HDisplay;
- crtc->bounds.y1 = 0;
- crtc->bounds.y2 = crtc->mode.VDisplay;
- pixman_f_transform_bounds (&f_crtc_to_fb, &crtc->bounds);
-
- if (damage)
- xf86CrtcDamageShadow (crtc);
-
- /* All done */
- return TRUE;
-}
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * 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 the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The 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 COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE 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.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#else
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "xf86.h"
+#include "xf86DDC.h"
+#include "fb.h"
+#include "windowstr.h"
+#include "xf86Crtc.h"
+#include "xf86Modes.h"
+#include "xf86RandR12.h"
+#include "X11/extensions/render.h"
+#include "X11/extensions/dpmsconst.h"
+#include "X11/Xatom.h"
+
+/* borrowed from composite extension, move to Render and publish? */
+
+static VisualPtr
+compGetWindowVisual (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ VisualID vid = wVisual (pWin);
+ int i;
+
+ for (i = 0; i < pScreen->numVisuals; i++)
+ if (pScreen->visuals[i].vid == vid)
+ return &pScreen->visuals[i];
+ return 0;
+}
+
+static PictFormatPtr
+compWindowFormat (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ return PictureMatchVisual (pScreen, pWin->drawable.depth,
+ compGetWindowVisual (pWin));
+}
+
+#define F(x) IntToxFixed(x)
+
+#define toF(x) ((float) (x) / 65536.0f)
+
+static void
+xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
+{
+ ScrnInfoPtr scrn = crtc->scrn;
+ ScreenPtr screen = scrn->pScreen;
+ WindowPtr root = screen->root;
+ PixmapPtr dst_pixmap = crtc->rotatedPixmap;
+ PictFormatPtr format = compWindowFormat (screen->root);
+ int error;
+ PicturePtr src, dst;
+ int n = RegionNumRects(region);
+ BoxPtr b = RegionRects(region);
+ XID include_inferiors = IncludeInferiors;
+
+ src = CreatePicture (None,
+ &root->drawable,
+ format,
+ CPSubwindowMode,
+ &include_inferiors,
+ serverClient,
+ &error);
+ if (!src)
+ return;
+
+ dst = CreatePicture (None,
+ &dst_pixmap->drawable,
+ format,
+ 0L,
+ NULL,
+ serverClient,
+ &error);
+ if (!dst)
+ return;
+
+ error = SetPictureTransform (src, &crtc->crtc_to_framebuffer);
+ if (error)
+ return;
+ if (crtc->transform_in_use && crtc->filter)
+ SetPicturePictFilter (src, crtc->filter,
+ crtc->params, crtc->nparams);
+
+ if (crtc->shadowClear)
+ {
+ CompositePicture (PictOpSrc,
+ src, NULL, dst,
+ 0, 0, 0, 0, 0, 0,
+ crtc->mode.HDisplay, crtc->mode.VDisplay);
+ crtc->shadowClear = FALSE;
+ }
+ else
+ {
+ while (n--)
+ {
+ BoxRec dst_box;
+
+ dst_box = *b;
+ dst_box.x1 -= crtc->filter_width >> 1;
+ dst_box.x2 += crtc->filter_width >> 1;
+ dst_box.y1 -= crtc->filter_height >> 1;
+ dst_box.y2 += crtc->filter_height >> 1;
+ pixman_f_transform_bounds (&crtc->f_framebuffer_to_crtc, &dst_box);
+ CompositePicture (PictOpSrc,
+ src, NULL, dst,
+ dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1,
+ dst_box.x2 - dst_box.x1,
+ dst_box.y2 - dst_box.y1);
+ b++;
+ }
+ }
+ FreePicture (src, None);
+ FreePicture (dst, None);
+}
+
+static void
+xf86CrtcDamageShadow (xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ BoxRec damage_box;
+ RegionRec damage_region;
+ ScreenPtr pScreen = pScrn->pScreen;
+
+ damage_box.x1 = 0;
+ damage_box.x2 = crtc->mode.HDisplay;
+ damage_box.y1 = 0;
+ damage_box.y2 = crtc->mode.VDisplay;
+ if (!pixman_transform_bounds (&crtc->crtc_to_framebuffer, &damage_box))
+ {
+ damage_box.x1 = 0;
+ damage_box.y1 = 0;
+ damage_box.x2 = pScreen->width;
+ damage_box.y2 = pScreen->height;
+ }
+ if (damage_box.x1 < 0) damage_box.x1 = 0;
+ if (damage_box.y1 < 0) damage_box.y1 = 0;
+ if (damage_box.x2 > pScreen->width) damage_box.x2 = pScreen->width;
+ if (damage_box.y2 > pScreen->height) damage_box.y2 = pScreen->height;
+ RegionInit(&damage_region, &damage_box, 1);
+ DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+ &damage_region);
+ RegionUninit(&damage_region);
+ crtc->shadowClear = TRUE;
+}
+
+static void
+xf86RotatePrepare (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->rotatedData && !crtc->rotatedPixmap)
+ {
+ crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
+ crtc->rotatedData,
+ crtc->mode.HDisplay,
+ crtc->mode.VDisplay);
+ if (!xf86_config->rotation_damage_registered)
+ {
+ /* Hook damage to screen pixmap */
+ DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+ xf86_config->rotation_damage);
+ xf86_config->rotation_damage_registered = TRUE;
+ EnableLimitedSchedulingLatency();
+ }
+
+ xf86CrtcDamageShadow (crtc);
+ }
+ }
+}
+
+static Bool
+xf86RotateRedisplay(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ DamagePtr damage = xf86_config->rotation_damage;
+ RegionPtr region;
+
+ if (!damage)
+ return FALSE;
+ xf86RotatePrepare (pScreen);
+ region = DamageRegion(damage);
+ if (RegionNotEmpty(region))
+ {
+ int c;
+ SourceValidateProcPtr SourceValidate;
+
+ /*
+ * SourceValidate is used by the software cursor code
+ * to pull the cursor off of the screen when reading
+ * bits from the frame buffer. Bypassing this function
+ * leaves the software cursor in place
+ */
+ SourceValidate = pScreen->SourceValidate;
+ pScreen->SourceValidate = NULL;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->transform_in_use && crtc->enabled)
+ {
+ RegionRec crtc_damage;
+
+ /* compute portion of damage that overlaps crtc */
+ RegionInit(&crtc_damage, &crtc->bounds, 1);
+ RegionIntersect(&crtc_damage, &crtc_damage, region);
+
+ /* update damaged region */
+ if (RegionNotEmpty(&crtc_damage))
+ xf86RotateCrtcRedisplay (crtc, &crtc_damage);
+
+ RegionUninit(&crtc_damage);
+ }
+ }
+ pScreen->SourceValidate = SourceValidate;
+ DamageEmpty(damage);
+ }
+ return TRUE;
+}
+
+static void
+xf86RotateBlockHandler(int screenNum, pointer blockData,
+ pointer pTimeout, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ ScrnInfoPtr pScrn = xf86Screens[screenNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ Bool rotation_active;
+
+ rotation_active = xf86RotateRedisplay(pScreen);
+ pScreen->BlockHandler = xf86_config->BlockHandler;
+ (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
+ /* cannot avoid re-wrapping until all wrapping is audited */
+ xf86_config->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = xf86RotateBlockHandler;
+}
+
+void
+xf86RotateDestroy (xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ ScreenPtr pScreen = pScrn->pScreen;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int c;
+
+ /* Free memory from rotation */
+ if (crtc->rotatedPixmap || crtc->rotatedData)
+ {
+ crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap, crtc->rotatedData);
+ crtc->rotatedPixmap = NULL;
+ crtc->rotatedData = NULL;
+ }
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ if (xf86_config->crtc[c]->transform_in_use)
+ return;
+
+ /*
+ * Clean up damage structures when no crtcs are rotated
+ */
+ if (xf86_config->rotation_damage)
+ {
+ /* Free damage structure */
+ if (xf86_config->rotation_damage_registered)
+ {
+ DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+ xf86_config->rotation_damage);
+ xf86_config->rotation_damage_registered = FALSE;
+ DisableLimitedSchedulingLatency();
+ }
+ DamageDestroy (xf86_config->rotation_damage);
+ xf86_config->rotation_damage = NULL;
+ }
+}
+
+void
+xf86RotateFreeShadow(ScrnInfoPtr pScrn)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int c;
+
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ if (crtc->rotatedPixmap || crtc->rotatedData) {
+ crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
+ crtc->rotatedData);
+ crtc->rotatedPixmap = NULL;
+ crtc->rotatedData = NULL;
+ }
+ }
+}
+
+void
+xf86RotateCloseScreen (ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ xf86RotateDestroy (xf86_config->crtc[c]);
+}
+
+static Bool
+xf86CrtcFitsScreen (xf86CrtcPtr crtc, struct pict_f_transform *crtc_to_fb)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ BoxRec b;
+
+ /* When called before PreInit, the driver is
+ * presumably doing load detect
+ */
+ if (pScrn->virtualX == 0 || pScrn->virtualY == 0)
+ return TRUE;
+
+ b.x1 = 0;
+ b.y1 = 0;
+ b.x2 = crtc->mode.HDisplay;
+ b.y2 = crtc->mode.VDisplay;
+ if (crtc_to_fb)
+ pixman_f_transform_bounds (crtc_to_fb, &b);
+ else {
+ b.x1 += crtc->x;
+ b.y1 += crtc->y;
+ b.x2 += crtc->x;
+ b.y2 += crtc->y;
+ }
+
+ return (0 <= b.x1 && b.x2 <= pScrn->virtualX &&
+ 0 <= b.y1 && b.y2 <= pScrn->virtualY);
+}
+
+Bool
+xf86CrtcRotate (xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
+ ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+ PictTransform crtc_to_fb;
+ struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc;
+ xFixed *new_params = NULL;
+ int new_nparams = 0;
+ PictFilterPtr new_filter = NULL;
+ int new_width = 0;
+ int new_height = 0;
+ RRTransformPtr transform = NULL;
+ Bool damage = FALSE;
+
+ if (crtc->transformPresent)
+ transform = &crtc->transform;
+
+ if (!RRTransformCompute (crtc->x, crtc->y,
+ crtc->mode.HDisplay, crtc->mode.VDisplay,
+ crtc->rotation,
+ transform,
+
+ &crtc_to_fb,
+ &f_crtc_to_fb,
+ &f_fb_to_crtc) &&
+ xf86CrtcFitsScreen (crtc, &f_crtc_to_fb))
+ {
+ /*
+ * If the untranslated transformation is the identity,
+ * disable the shadow buffer
+ */
+ xf86RotateDestroy (crtc);
+ crtc->transform_in_use = FALSE;
+ free(new_params);
+ new_params = NULL;
+ new_nparams = 0;
+ new_filter = NULL;
+ new_width = 0;
+ new_height = 0;
+ }
+ else
+ {
+ /*
+ * these are the size of the shadow pixmap, which
+ * matches the mode, not the pre-rotated copy in the
+ * frame buffer
+ */
+ int width = crtc->mode.HDisplay;
+ int height = crtc->mode.VDisplay;
+ void *shadowData = crtc->rotatedData;
+ PixmapPtr shadow = crtc->rotatedPixmap;
+ int old_width = shadow ? shadow->drawable.width : 0;
+ int old_height = shadow ? shadow->drawable.height : 0;
+
+ /* Allocate memory for rotation */
+ if (old_width != width || old_height != height)
+ {
+ if (shadow || shadowData)
+ {
+ crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
+ crtc->rotatedPixmap = NULL;
+ crtc->rotatedData = NULL;
+ }
+ shadowData = crtc->funcs->shadow_allocate (crtc, width, height);
+ if (!shadowData)
+ goto bail1;
+ crtc->rotatedData = shadowData;
+ /* shadow will be damaged in xf86RotatePrepare */
+ }
+ else
+ {
+ /* mark shadowed area as damaged so it will be repainted */
+ damage = TRUE;
+ }
+
+ if (!xf86_config->rotation_damage)
+ {
+ /* Create damage structure */
+ xf86_config->rotation_damage = DamageCreate (NULL, NULL,
+ DamageReportNone,
+ TRUE, pScreen, pScreen);
+ if (!xf86_config->rotation_damage)
+ goto bail2;
+
+ /* Wrap block handler */
+ if (!xf86_config->BlockHandler) {
+ xf86_config->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = xf86RotateBlockHandler;
+ }
+ }
+#ifdef RANDR_12_INTERFACE
+ if (transform)
+ {
+ if (transform->nparams) {
+ new_params = malloc(transform->nparams * sizeof (xFixed));
+ if (new_params) {
+ memcpy (new_params, transform->params,
+ transform->nparams * sizeof (xFixed));
+ new_nparams = transform->nparams;
+ new_filter = transform->filter;
+ }
+ } else
+ new_filter = transform->filter;
+ if (new_filter)
+ {
+ new_width = new_filter->width;
+ new_height = new_filter->height;
+ }
+ }
+#endif
+
+ if (0)
+ {
+ bail2:
+ if (shadow || shadowData)
+ {
+ crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
+ crtc->rotatedPixmap = NULL;
+ crtc->rotatedData = NULL;
+ }
+ bail1:
+ if (old_width && old_height)
+ crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
+ NULL,
+ old_width,
+ old_height);
+ return FALSE;
+ }
+ crtc->transform_in_use = TRUE;
+ }
+ crtc->crtc_to_framebuffer = crtc_to_fb;
+ crtc->f_crtc_to_framebuffer = f_crtc_to_fb;
+ crtc->f_framebuffer_to_crtc = f_fb_to_crtc;
+ free(crtc->params);
+ crtc->params = new_params;
+ crtc->nparams = new_nparams;
+ crtc->filter = new_filter;
+ crtc->filter_width = new_width;
+ crtc->filter_height = new_height;
+ crtc->bounds.x1 = 0;
+ crtc->bounds.x2 = crtc->mode.HDisplay;
+ crtc->bounds.y1 = 0;
+ crtc->bounds.y2 = crtc->mode.VDisplay;
+ pixman_f_transform_bounds (&f_crtc_to_fb, &crtc->bounds);
+
+ if (damage)
+ xf86CrtcDamageShadow (crtc);
+
+ /* All done */
+ return TRUE;
+}
diff --git a/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c b/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c
index 123eb17d1..7775e5dff 100644
--- a/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c
+++ b/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c
@@ -1,756 +1,756 @@
-/*
- * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
- * Copyright 1993 by David Wexelblat <dwex@goblin.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 names of Rich Murphey and David Wexelblat
- * not be used in advertising or publicity pertaining to distribution of
- * the software without specific, written prior permission. Rich Murphey and
- * David Wexelblat make no representations about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- *
- * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO
- * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID WEXELBLAT 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.
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-
-#include "compiler.h"
-
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-
-#include <sys/utsname.h>
-#include <sys/ioctl.h>
-#include <stdlib.h>
-#include <errno.h>
-
-static Bool KeepTty = FALSE;
-static int devConsoleFd = -1;
-#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
-static int VTnum = -1;
-static int initialVT = -1;
-static Bool ShareVTs = FALSE;
-#endif
-
-#ifdef PCCONS_SUPPORT
-/* Stock 0.1 386bsd pccons console driver interface */
-#define PCCONS_CONSOLE_DEV1 "/dev/ttyv0"
-#define PCCONS_CONSOLE_DEV2 "/dev/vga"
-#define PCCONS_CONSOLE_MODE O_RDWR|O_NDELAY
-#endif
-
-#ifdef SYSCONS_SUPPORT
-/* The FreeBSD 1.1 version syscons driver uses /dev/ttyv0 */
-#define SYSCONS_CONSOLE_DEV1 "/dev/ttyv0"
-#define SYSCONS_CONSOLE_DEV2 "/dev/vga"
-#define SYSCONS_CONSOLE_MODE O_RDWR|O_NDELAY
-#endif
-
-#ifdef PCVT_SUPPORT
-/* Hellmuth Michaelis' pcvt driver */
-#ifndef __OpenBSD__
-# define PCVT_CONSOLE_DEV "/dev/ttyv0"
-#else
-# define PCVT_CONSOLE_DEV "/dev/ttyC0"
-#endif
-#define PCVT_CONSOLE_MODE O_RDWR|O_NDELAY
-#endif
-
-#if defined(WSCONS_SUPPORT) && defined(__NetBSD__)
-/* NetBSD's new console driver */
-#define WSCONS_PCVT_COMPAT_CONSOLE_DEV "/dev/ttyE0"
-#endif
-
-#ifdef __GLIBC__
-#define setpgrp setpgid
-#endif
-
-#define CHECK_DRIVER_MSG \
- "Check your kernel's console driver configuration and /dev entries"
-
-static char *supported_drivers[] = {
-#ifdef PCCONS_SUPPORT
- "pccons (with X support)",
-#endif
-#ifdef SYSCONS_SUPPORT
- "syscons",
-#endif
-#ifdef PCVT_SUPPORT
- "pcvt",
-#endif
-#ifdef WSCONS_SUPPORT
- "wscons",
-#endif
-};
-
-
-/*
- * Functions to probe for the existance of a supported console driver.
- * Any function returns either a valid file descriptor (driver probed
- * succesfully), -1 (driver not found), or uses FatalError() if the
- * driver was found but proved to not support the required mode to run
- * an X server.
- */
-
-typedef int (*xf86ConsOpen_t)(void);
-
-#ifdef PCCONS_SUPPORT
-static int xf86OpenPccons(void);
-#endif /* PCCONS_SUPPORT */
-
-#ifdef SYSCONS_SUPPORT
-static int xf86OpenSyscons(void);
-#endif /* SYSCONS_SUPPORT */
-
-#ifdef PCVT_SUPPORT
-static int xf86OpenPcvt(void);
-#endif /* PCVT_SUPPORT */
-
-#ifdef WSCONS_SUPPORT
-static int xf86OpenWScons(void);
-#endif
-
-/*
- * The sequence of the driver probes is important; start with the
- * driver that is best distinguishable, and end with the most generic
- * driver. (Otherwise, pcvt would also probe as syscons, and either
- * pcvt or syscons might succesfully probe as pccons.)
- */
-static xf86ConsOpen_t xf86ConsTab[] = {
-#ifdef PCVT_SUPPORT
- xf86OpenPcvt,
-#endif
-#ifdef SYSCONS_SUPPORT
- xf86OpenSyscons,
-#endif
-#ifdef PCCONS_SUPPORT
- xf86OpenPccons,
-#endif
-#ifdef WSCONS_SUPPORT
- xf86OpenWScons,
-#endif
- (xf86ConsOpen_t)NULL
-};
-
-
-void
-xf86OpenConsole()
-{
- int i, fd = -1;
- xf86ConsOpen_t *driver;
-#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
- int result;
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
- struct utsname uts;
-#endif
- vtmode_t vtmode;
-#endif
-
- if (serverGeneration == 1)
- {
- /* check if we are run with euid==0 */
- if (geteuid() != 0)
- {
- FatalError("xf86OpenConsole: Server must be suid root");
- }
-
- if (!KeepTty)
- {
- /*
- * detaching the controlling tty solves problems of kbd character
- * loss. This is not interesting for CO driver, because it is
- * exclusive.
- */
- setpgrp(0, getpid());
- if ((i = open("/dev/tty",O_RDWR)) >= 0)
- {
- ioctl(i,TIOCNOTTY,(char *)0);
- close(i);
- }
- }
-
- /* detect which driver we are running on */
- for (driver = xf86ConsTab; *driver; driver++)
- {
- if ((fd = (*driver)()) >= 0)
- break;
- }
-
- /* Check that a supported console driver was found */
- if (fd < 0)
- {
- char cons_drivers[80] = {0, };
- for (i = 0; i < sizeof(supported_drivers) / sizeof(char *); i++)
- {
- if (i)
- {
- strcat(cons_drivers, ", ");
- }
- strcat(cons_drivers, supported_drivers[i]);
- }
- FatalError(
- "%s: No console driver found\n\tSupported drivers: %s\n\t%s",
- "xf86OpenConsole", cons_drivers, CHECK_DRIVER_MSG);
- }
-#if 0 /* stdin is already closed in OsInit() */
- fclose(stdin);
-#endif
- xf86Info.consoleFd = fd;
- xf86Info.screenFd = fd;
-
- switch (xf86Info.consType)
- {
-#ifdef PCCONS_SUPPORT
- case PCCONS:
- if (ioctl (xf86Info.consoleFd, CONSOLE_X_MODE_ON, 0) < 0)
- {
- FatalError("%s: CONSOLE_X_MODE_ON failed (%s)\n%s",
- "xf86OpenConsole", strerror(errno),
- CHECK_DRIVER_MSG);
- }
- /*
- * Hack to prevent keyboard hanging when syslogd closes
- * /dev/console
- */
- if ((devConsoleFd = open("/dev/console", O_WRONLY,0)) < 0)
- {
- xf86Msg(X_WARNING,
- "xf86OpenConsole: couldn't open /dev/console (%s)\n",
- strerror(errno));
- }
- break;
-#endif
-#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
- case SYSCONS:
- /* as of FreeBSD 2.2.8, syscons driver does not need the #1 vt
- * switching anymore. Here we check for FreeBSD 3.1 and up.
- * Add cases for other *BSD that behave the same.
- */
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
- uname (&uts);
- i = atof(uts.release) * 100;
- if (i >= 310) goto acquire_vt;
-#endif
- /* otherwise fall through */
- case PCVT:
-#if !(defined(__NetBSD__) && (__NetBSD_Version__ >= 200000000))
- /*
- * First activate the #1 VT. This is a hack to allow a server
- * to be started while another one is active. There should be
- * a better way.
- */
- if (initialVT != 1) {
-
- if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, 1) != 0)
- {
- xf86Msg(X_WARNING,
- "xf86OpenConsole: VT_ACTIVATE failed\n");
- }
- sleep(1);
- }
-#endif
-acquire_vt:
- if (!ShareVTs) {
- /*
- * now get the VT
- */
- SYSCALL(result =
- ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno));
- if (result != 0)
- {
- xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
- }
- SYSCALL(result =
- ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno));
- if (result != 0)
- {
- xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
- }
-
- signal(SIGUSR1, xf86VTRequest);
-
- vtmode.mode = VT_PROCESS;
- vtmode.relsig = SIGUSR1;
- vtmode.acqsig = SIGUSR1;
- vtmode.frsig = SIGUSR1;
- if (ioctl(xf86Info.consoleFd, VT_SETMODE, &vtmode) < 0)
- {
- FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed");
- }
- #if !defined(USE_DEV_IO) && !defined(USE_I386_IOPL)
- if (ioctl(xf86Info.consoleFd, KDENABIO, 0) < 0)
- {
- FatalError("xf86OpenConsole: KDENABIO failed (%s)",
- strerror(errno));
- }
- #endif
- if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
- {
- FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed");
- }
- } else { /* ShareVTs */
- close(xf86Info.consoleFd);
- }
- break;
-#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
-#ifdef WSCONS_SUPPORT
- case WSCONS:
- /* Nothing to do */
- break;
-#endif
- }
- }
- else
- {
- /* serverGeneration != 1 */
-#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
- if (!ShareVTs) if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT)
- {
- if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
- {
- xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
- }
- }
-#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
- }
- return;
-}
-
-
-#ifdef PCCONS_SUPPORT
-
-static int
-xf86OpenPccons()
-{
- int fd = -1;
-
- if ((fd = open(PCCONS_CONSOLE_DEV1, PCCONS_CONSOLE_MODE, 0))
- >= 0 ||
- (fd = open(PCCONS_CONSOLE_DEV2, PCCONS_CONSOLE_MODE, 0))
- >= 0)
- {
- if (ioctl(fd, CONSOLE_X_MODE_OFF, 0) < 0)
- {
- FatalError(
- "%s: CONSOLE_X_MODE_OFF failed (%s)\n%s\n%s",
- "xf86OpenPccons",
- strerror(errno),
- "Was expecting pccons driver with X support",
- CHECK_DRIVER_MSG);
- }
- xf86Info.consType = PCCONS;
- xf86Msg(X_PROBED, "Using pccons driver with X support\n");
- }
- return fd;
-}
-
-#endif /* PCCONS_SUPPORT */
-
-#ifdef SYSCONS_SUPPORT
-
-static int
-xf86OpenSyscons()
-{
- int fd = -1;
- vtmode_t vtmode;
- char vtname[12];
- struct stat status;
- long syscons_version;
- MessageType from;
-
- /* Check for syscons */
- if ((fd = open(SYSCONS_CONSOLE_DEV1, SYSCONS_CONSOLE_MODE, 0)) >= 0
- || (fd = open(SYSCONS_CONSOLE_DEV2, SYSCONS_CONSOLE_MODE, 0)) >= 0)
- {
- if (ioctl(fd, VT_GETMODE, &vtmode) >= 0)
- {
- /* Get syscons version */
- if (ioctl(fd, CONS_GETVERS, &syscons_version) < 0)
- {
- syscons_version = 0;
- }
-
- xf86Info.vtno = VTnum;
- from = X_CMDLINE;
-
-#ifdef VT_GETACTIVE
- if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0)
- initialVT = -1;
-#endif
- if (ShareVTs)
- xf86Info.vtno = initialVT;
-
- if (xf86Info.vtno == -1)
- {
- /*
- * For old syscons versions (<0x100), VT_OPENQRY returns
- * the current VT rather than the next free VT. In this
- * case, the server gets started on the current VT instead
- * of the next free VT.
- */
-
-#if 0
- /* check for the fixed VT_OPENQRY */
- if (syscons_version >= 0x100)
- {
-#endif
- if (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0)
- {
- /* No free VTs */
- xf86Info.vtno = -1;
- }
-#if 0
- }
-#endif
-
- if (xf86Info.vtno == -1)
- {
- /*
- * All VTs are in use. If initialVT was found, use it.
- * Otherwise, if stdin is a VT, use that one.
- * XXX stdin is already closed, so this won't work.
- */
- if (initialVT != -1)
- {
- xf86Info.vtno = initialVT;
- }
- else if ((fstat(0, &status) >= 0)
- && S_ISCHR(status.st_mode)
- && (ioctl(0, VT_GETMODE, &vtmode) >= 0))
- {
- /* stdin is a VT */
- xf86Info.vtno = minor(status.st_rdev) + 1;
- }
- else
- {
- if (syscons_version >= 0x100)
- {
- FatalError("%s: Cannot find a free VT",
- "xf86OpenSyscons");
- }
- /* Should no longer reach here */
- FatalError("%s: %s %s\n\t%s %s",
- "xf86OpenSyscons",
- "syscons versions prior to 1.0 require",
- "either the",
- "server's stdin be a VT",
- "or the use of the vtxx server option");
- }
- }
- from = X_PROBED;
- }
-
- close(fd);
-#ifndef __OpenBSD__
- sprintf(vtname, "/dev/ttyv%01x", xf86Info.vtno - 1);
-#else
- sprintf(vtname, "/dev/ttyC%01x", xf86Info.vtno - 1);
-#endif
- if ((fd = open(vtname, SYSCONS_CONSOLE_MODE, 0)) < 0)
- {
- FatalError("xf86OpenSyscons: Cannot open %s (%s)",
- vtname, strerror(errno));
- }
- if (ioctl(fd, VT_GETMODE, &vtmode) < 0)
- {
- FatalError("xf86OpenSyscons: VT_GETMODE failed");
- }
- xf86Info.consType = SYSCONS;
- xf86Msg(X_PROBED, "Using syscons driver with X support");
- if (syscons_version >= 0x100)
- {
- xf86ErrorF(" (version %ld.%ld)\n", syscons_version >> 8,
- syscons_version & 0xFF);
- }
- else
- {
- xf86ErrorF(" (version 0.x)\n");
- }
- xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
- }
- else
- {
- /* VT_GETMODE failed, probably not syscons */
- close(fd);
- fd = -1;
- }
- }
- return fd;
-}
-
-#endif /* SYSCONS_SUPPORT */
-
-
-#ifdef PCVT_SUPPORT
-
-static int
-xf86OpenPcvt()
-{
- /* This looks much like syscons, since pcvt is API compatible */
- int fd = -1;
- vtmode_t vtmode;
- char vtname[12], *vtprefix;
- struct stat status;
- struct pcvtid pcvt_version;
-
-#ifndef __OpenBSD__
- vtprefix = "/dev/ttyv";
-#else
- vtprefix = "/dev/ttyC";
-#endif
-
- fd = open(PCVT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0);
-#ifdef WSCONS_PCVT_COMPAT_CONSOLE_DEV
- if (fd < 0)
- {
- fd = open(WSCONS_PCVT_COMPAT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0);
- vtprefix = "/dev/ttyE";
- }
-#endif
- if (fd >= 0)
- {
- if (ioctl(fd, VGAPCVTID, &pcvt_version) >= 0)
- {
- if(ioctl(fd, VT_GETMODE, &vtmode) < 0)
- {
- FatalError("%s: VT_GETMODE failed\n%s%s\n%s",
- "xf86OpenPcvt",
- "Found pcvt driver but X11 seems to be",
- " not supported.", CHECK_DRIVER_MSG);
- }
-
- xf86Info.vtno = VTnum;
-
- if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0)
- initialVT = -1;
-
- if (xf86Info.vtno == -1)
- {
- if (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0)
- {
- /* No free VTs */
- xf86Info.vtno = -1;
- }
-
- if (xf86Info.vtno == -1)
- {
- /*
- * All VTs are in use. If initialVT was found, use it.
- * Otherwise, if stdin is a VT, use that one.
- * XXX stdin is already closed, so this won't work.
- */
- if (initialVT != -1)
- {
- xf86Info.vtno = initialVT;
- }
- else if ((fstat(0, &status) >= 0)
- && S_ISCHR(status.st_mode)
- && (ioctl(0, VT_GETMODE, &vtmode) >= 0))
- {
- /* stdin is a VT */
- xf86Info.vtno = minor(status.st_rdev) + 1;
- }
- else
- {
- FatalError("%s: Cannot find a free VT",
- "xf86OpenPcvt");
- }
- }
- }
-
- close(fd);
- sprintf(vtname, "%s%01x", vtprefix, xf86Info.vtno - 1);
- if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0)
- {
- ErrorF("xf86OpenPcvt: Cannot open %s (%s)",
- vtname, strerror(errno));
- xf86Info.vtno = initialVT;
- sprintf(vtname, "%s%01x", vtprefix, xf86Info.vtno - 1);
- if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0) {
- FatalError("xf86OpenPcvt: Cannot open %s (%s)",
- vtname, strerror(errno));
- }
- }
- if (ioctl(fd, VT_GETMODE, &vtmode) < 0)
- {
- FatalError("xf86OpenPcvt: VT_GETMODE failed");
- }
- xf86Info.consType = PCVT;
-#ifdef WSCONS_SUPPORT
- xf86Msg(X_PROBED,
- "Using wscons driver on %s in pcvt compatibility mode "
- "(version %d.%d)\n", vtname,
- pcvt_version.rmajor, pcvt_version.rminor);
-#else
- xf86Msg(X_PROBED, "Using pcvt driver (version %d.%d)\n",
- pcvt_version.rmajor, pcvt_version.rminor);
-#endif
- }
- else
- {
- /* Not pcvt */
- close(fd);
- fd = -1;
- }
- }
- return fd;
-}
-
-#endif /* PCVT_SUPPORT */
-
-#ifdef WSCONS_SUPPORT
-
-static int
-xf86OpenWScons()
-{
- int fd = -1;
- int mode = WSDISPLAYIO_MODE_MAPPED;
- int i;
- char ttyname[16];
-
- /* XXX Is this ok? */
- for (i = 0; i < 8; i++) {
-#if defined(__NetBSD__)
- sprintf(ttyname, "/dev/ttyE%d", i);
-#elif defined(__OpenBSD__)
- sprintf(ttyname, "/dev/ttyC%x", i);
-#endif
- if ((fd = open(ttyname, 2)) != -1)
- break;
- }
- if (fd != -1) {
- if (ioctl(fd, WSDISPLAYIO_SMODE, &mode) < 0) {
- FatalError("%s: WSDISPLAYIO_MODE_MAPPED failed (%s)\n%s",
- "xf86OpenConsole", strerror(errno),
- CHECK_DRIVER_MSG);
- }
- xf86Info.consType = WSCONS;
- xf86Msg(X_PROBED, "Using wscons driver\n");
- }
- return fd;
-}
-
-#endif /* WSCONS_SUPPORT */
-
-void
-xf86CloseConsole()
-{
-#if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT)
- struct vt_mode VT;
-#endif
-
- if (ShareVTs) return;
-
- switch (xf86Info.consType)
- {
-#ifdef PCCONS_SUPPORT
- case PCCONS:
- ioctl (xf86Info.consoleFd, CONSOLE_X_MODE_OFF, 0);
- break;
-#endif /* PCCONS_SUPPORT */
-#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
- case SYSCONS:
- case PCVT:
- ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); /* Back to text mode */
- if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
- {
- VT.mode = VT_AUTO;
- ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* dflt vt handling */
- }
-#if !defined(OpenBSD) && !defined(USE_DEV_IO) && !defined(USE_I386_IOPL)
- if (ioctl(xf86Info.consoleFd, KDDISABIO, 0) < 0)
- {
- xf86FatalError("xf86CloseConsole: KDDISABIO failed (%s)",
- strerror(errno));
- }
-#endif
- if (initialVT != -1)
- ioctl(xf86Info.consoleFd, VT_ACTIVATE, initialVT);
- break;
-#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
-#ifdef WSCONS_SUPPORT
- case WSCONS:
- {
- int mode = WSDISPLAYIO_MODE_EMUL;
- ioctl(xf86Info.screenFd, WSDISPLAYIO_SMODE, &mode);
- break;
- }
-#endif
- }
-
- if (xf86Info.screenFd != xf86Info.consoleFd)
- {
- close(xf86Info.screenFd);
- close(xf86Info.consoleFd);
- if ((xf86Info.consoleFd = open("/dev/console",O_RDONLY,0)) <0)
- {
- xf86FatalError("xf86CloseConsole: Cannot open /dev/console (%s)",
- strerror(errno));
- }
- }
- close(xf86Info.consoleFd);
- if (devConsoleFd >= 0)
- close(devConsoleFd);
- return;
-}
-
-int
-xf86ProcessArgument(int argc, char *argv[], int i)
-{
- /*
- * Keep server from detaching from controlling tty. This is useful
- * when debugging (so the server can receive keyboard signals.
- */
- if (!strcmp(argv[i], "-keeptty"))
- {
- KeepTty = TRUE;
- return 1;
- }
-#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
- if (!strcmp(argv[i], "-sharevts"))
- {
- ShareVTs = TRUE;
- return 1;
- }
- if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
- {
- if (sscanf(argv[i], "vt%2d", &VTnum) == 0 ||
- VTnum < 1 || VTnum > 12)
- {
- UseMsg();
- VTnum = -1;
- return 0;
- }
- return 1;
- }
-#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
- return 0;
-}
-
-void
-xf86UseMsg()
-{
-#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
- ErrorF("vtXX use the specified VT number (1-12)\n");
- ErrorF("-sharevts share VTs with another X server\n");
-#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
- ErrorF("-keeptty ");
- ErrorF("don't detach controlling tty (for debugging only)\n");
- return;
-}
+/*
+ * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+ * Copyright 1993 by David Wexelblat <dwex@goblin.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 names of Rich Murphey and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Rich Murphey and
+ * David Wexelblat make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID WEXELBLAT 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.
+ *
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#include <sys/utsname.h>
+#include <sys/ioctl.h>
+#include <stdlib.h>
+#include <errno.h>
+
+static Bool KeepTty = FALSE;
+static int devConsoleFd = -1;
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+static int VTnum = -1;
+static int initialVT = -1;
+static Bool ShareVTs = FALSE;
+#endif
+
+#ifdef PCCONS_SUPPORT
+/* Stock 0.1 386bsd pccons console driver interface */
+#define PCCONS_CONSOLE_DEV1 "/dev/ttyv0"
+#define PCCONS_CONSOLE_DEV2 "/dev/vga"
+#define PCCONS_CONSOLE_MODE O_RDWR|O_NDELAY
+#endif
+
+#ifdef SYSCONS_SUPPORT
+/* The FreeBSD 1.1 version syscons driver uses /dev/ttyv0 */
+#define SYSCONS_CONSOLE_DEV1 "/dev/ttyv0"
+#define SYSCONS_CONSOLE_DEV2 "/dev/vga"
+#define SYSCONS_CONSOLE_MODE O_RDWR|O_NDELAY
+#endif
+
+#ifdef PCVT_SUPPORT
+/* Hellmuth Michaelis' pcvt driver */
+#ifndef __OpenBSD__
+# define PCVT_CONSOLE_DEV "/dev/ttyv0"
+#else
+# define PCVT_CONSOLE_DEV "/dev/ttyC0"
+#endif
+#define PCVT_CONSOLE_MODE O_RDWR|O_NDELAY
+#endif
+
+#if defined(WSCONS_SUPPORT) && defined(__NetBSD__)
+/* NetBSD's new console driver */
+#define WSCONS_PCVT_COMPAT_CONSOLE_DEV "/dev/ttyE0"
+#endif
+
+#ifdef __GLIBC__
+#define setpgrp setpgid
+#endif
+
+#define CHECK_DRIVER_MSG \
+ "Check your kernel's console driver configuration and /dev entries"
+
+static char *supported_drivers[] = {
+#ifdef PCCONS_SUPPORT
+ "pccons (with X support)",
+#endif
+#ifdef SYSCONS_SUPPORT
+ "syscons",
+#endif
+#ifdef PCVT_SUPPORT
+ "pcvt",
+#endif
+#ifdef WSCONS_SUPPORT
+ "wscons",
+#endif
+};
+
+
+/*
+ * Functions to probe for the existance of a supported console driver.
+ * Any function returns either a valid file descriptor (driver probed
+ * succesfully), -1 (driver not found), or uses FatalError() if the
+ * driver was found but proved to not support the required mode to run
+ * an X server.
+ */
+
+typedef int (*xf86ConsOpen_t)(void);
+
+#ifdef PCCONS_SUPPORT
+static int xf86OpenPccons(void);
+#endif /* PCCONS_SUPPORT */
+
+#ifdef SYSCONS_SUPPORT
+static int xf86OpenSyscons(void);
+#endif /* SYSCONS_SUPPORT */
+
+#ifdef PCVT_SUPPORT
+static int xf86OpenPcvt(void);
+#endif /* PCVT_SUPPORT */
+
+#ifdef WSCONS_SUPPORT
+static int xf86OpenWScons(void);
+#endif
+
+/*
+ * The sequence of the driver probes is important; start with the
+ * driver that is best distinguishable, and end with the most generic
+ * driver. (Otherwise, pcvt would also probe as syscons, and either
+ * pcvt or syscons might succesfully probe as pccons.)
+ */
+static xf86ConsOpen_t xf86ConsTab[] = {
+#ifdef PCVT_SUPPORT
+ xf86OpenPcvt,
+#endif
+#ifdef SYSCONS_SUPPORT
+ xf86OpenSyscons,
+#endif
+#ifdef PCCONS_SUPPORT
+ xf86OpenPccons,
+#endif
+#ifdef WSCONS_SUPPORT
+ xf86OpenWScons,
+#endif
+ (xf86ConsOpen_t)NULL
+};
+
+
+void
+xf86OpenConsole()
+{
+ int i, fd = -1;
+ xf86ConsOpen_t *driver;
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ int result;
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ struct utsname uts;
+#endif
+ vtmode_t vtmode;
+#endif
+
+ if (serverGeneration == 1)
+ {
+ /* check if we are run with euid==0 */
+ if (geteuid() != 0)
+ {
+ FatalError("xf86OpenConsole: Server must be suid root");
+ }
+
+ if (!KeepTty)
+ {
+ /*
+ * detaching the controlling tty solves problems of kbd character
+ * loss. This is not interesting for CO driver, because it is
+ * exclusive.
+ */
+ setpgrp(0, getpid());
+ if ((i = open("/dev/tty",O_RDWR)) >= 0)
+ {
+ ioctl(i,TIOCNOTTY,(char *)0);
+ close(i);
+ }
+ }
+
+ /* detect which driver we are running on */
+ for (driver = xf86ConsTab; *driver; driver++)
+ {
+ if ((fd = (*driver)()) >= 0)
+ break;
+ }
+
+ /* Check that a supported console driver was found */
+ if (fd < 0)
+ {
+ char cons_drivers[80] = {0, };
+ for (i = 0; i < sizeof(supported_drivers) / sizeof(char *); i++)
+ {
+ if (i)
+ {
+ strcat(cons_drivers, ", ");
+ }
+ strcat(cons_drivers, supported_drivers[i]);
+ }
+ FatalError(
+ "%s: No console driver found\n\tSupported drivers: %s\n\t%s",
+ "xf86OpenConsole", cons_drivers, CHECK_DRIVER_MSG);
+ }
+#if 0 /* stdin is already closed in OsInit() */
+ fclose(stdin);
+#endif
+ xf86Info.consoleFd = fd;
+ xf86Info.screenFd = fd;
+
+ switch (xf86Info.consType)
+ {
+#ifdef PCCONS_SUPPORT
+ case PCCONS:
+ if (ioctl (xf86Info.consoleFd, CONSOLE_X_MODE_ON, 0) < 0)
+ {
+ FatalError("%s: CONSOLE_X_MODE_ON failed (%s)\n%s",
+ "xf86OpenConsole", strerror(errno),
+ CHECK_DRIVER_MSG);
+ }
+ /*
+ * Hack to prevent keyboard hanging when syslogd closes
+ * /dev/console
+ */
+ if ((devConsoleFd = open("/dev/console", O_WRONLY,0)) < 0)
+ {
+ xf86Msg(X_WARNING,
+ "xf86OpenConsole: couldn't open /dev/console (%s)\n",
+ strerror(errno));
+ }
+ break;
+#endif
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ case SYSCONS:
+ /* as of FreeBSD 2.2.8, syscons driver does not need the #1 vt
+ * switching anymore. Here we check for FreeBSD 3.1 and up.
+ * Add cases for other *BSD that behave the same.
+ */
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ uname (&uts);
+ i = atof(uts.release) * 100;
+ if (i >= 310) goto acquire_vt;
+#endif
+ /* otherwise fall through */
+ case PCVT:
+#if !(defined(__NetBSD__) && (__NetBSD_Version__ >= 200000000))
+ /*
+ * First activate the #1 VT. This is a hack to allow a server
+ * to be started while another one is active. There should be
+ * a better way.
+ */
+ if (initialVT != 1) {
+
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, 1) != 0)
+ {
+ xf86Msg(X_WARNING,
+ "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ sleep(1);
+ }
+#endif
+acquire_vt:
+ if (!ShareVTs) {
+ /*
+ * now get the VT
+ */
+ SYSCALL(result =
+ ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno));
+ if (result != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ SYSCALL(result =
+ ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno));
+ if (result != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
+ }
+
+ signal(SIGUSR1, xf86VTRequest);
+
+ vtmode.mode = VT_PROCESS;
+ vtmode.relsig = SIGUSR1;
+ vtmode.acqsig = SIGUSR1;
+ vtmode.frsig = SIGUSR1;
+ if (ioctl(xf86Info.consoleFd, VT_SETMODE, &vtmode) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed");
+ }
+ #if !defined(USE_DEV_IO) && !defined(USE_I386_IOPL)
+ if (ioctl(xf86Info.consoleFd, KDENABIO, 0) < 0)
+ {
+ FatalError("xf86OpenConsole: KDENABIO failed (%s)",
+ strerror(errno));
+ }
+ #endif
+ if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
+ {
+ FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed");
+ }
+ } else { /* ShareVTs */
+ close(xf86Info.consoleFd);
+ }
+ break;
+#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
+#ifdef WSCONS_SUPPORT
+ case WSCONS:
+ /* Nothing to do */
+ break;
+#endif
+ }
+ }
+ else
+ {
+ /* serverGeneration != 1 */
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ if (!ShareVTs) if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT)
+ {
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ }
+#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
+ }
+ return;
+}
+
+
+#ifdef PCCONS_SUPPORT
+
+static int
+xf86OpenPccons()
+{
+ int fd = -1;
+
+ if ((fd = open(PCCONS_CONSOLE_DEV1, PCCONS_CONSOLE_MODE, 0))
+ >= 0 ||
+ (fd = open(PCCONS_CONSOLE_DEV2, PCCONS_CONSOLE_MODE, 0))
+ >= 0)
+ {
+ if (ioctl(fd, CONSOLE_X_MODE_OFF, 0) < 0)
+ {
+ FatalError(
+ "%s: CONSOLE_X_MODE_OFF failed (%s)\n%s\n%s",
+ "xf86OpenPccons",
+ strerror(errno),
+ "Was expecting pccons driver with X support",
+ CHECK_DRIVER_MSG);
+ }
+ xf86Info.consType = PCCONS;
+ xf86Msg(X_PROBED, "Using pccons driver with X support\n");
+ }
+ return fd;
+}
+
+#endif /* PCCONS_SUPPORT */
+
+#ifdef SYSCONS_SUPPORT
+
+static int
+xf86OpenSyscons()
+{
+ int fd = -1;
+ vtmode_t vtmode;
+ char vtname[12];
+ struct stat status;
+ long syscons_version;
+ MessageType from;
+
+ /* Check for syscons */
+ if ((fd = open(SYSCONS_CONSOLE_DEV1, SYSCONS_CONSOLE_MODE, 0)) >= 0
+ || (fd = open(SYSCONS_CONSOLE_DEV2, SYSCONS_CONSOLE_MODE, 0)) >= 0)
+ {
+ if (ioctl(fd, VT_GETMODE, &vtmode) >= 0)
+ {
+ /* Get syscons version */
+ if (ioctl(fd, CONS_GETVERS, &syscons_version) < 0)
+ {
+ syscons_version = 0;
+ }
+
+ xf86Info.vtno = VTnum;
+ from = X_CMDLINE;
+
+#ifdef VT_GETACTIVE
+ if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0)
+ initialVT = -1;
+#endif
+ if (ShareVTs)
+ xf86Info.vtno = initialVT;
+
+ if (xf86Info.vtno == -1)
+ {
+ /*
+ * For old syscons versions (<0x100), VT_OPENQRY returns
+ * the current VT rather than the next free VT. In this
+ * case, the server gets started on the current VT instead
+ * of the next free VT.
+ */
+
+#if 0
+ /* check for the fixed VT_OPENQRY */
+ if (syscons_version >= 0x100)
+ {
+#endif
+ if (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0)
+ {
+ /* No free VTs */
+ xf86Info.vtno = -1;
+ }
+#if 0
+ }
+#endif
+
+ if (xf86Info.vtno == -1)
+ {
+ /*
+ * All VTs are in use. If initialVT was found, use it.
+ * Otherwise, if stdin is a VT, use that one.
+ * XXX stdin is already closed, so this won't work.
+ */
+ if (initialVT != -1)
+ {
+ xf86Info.vtno = initialVT;
+ }
+ else if ((fstat(0, &status) >= 0)
+ && S_ISCHR(status.st_mode)
+ && (ioctl(0, VT_GETMODE, &vtmode) >= 0))
+ {
+ /* stdin is a VT */
+ xf86Info.vtno = minor(status.st_rdev) + 1;
+ }
+ else
+ {
+ if (syscons_version >= 0x100)
+ {
+ FatalError("%s: Cannot find a free VT",
+ "xf86OpenSyscons");
+ }
+ /* Should no longer reach here */
+ FatalError("%s: %s %s\n\t%s %s",
+ "xf86OpenSyscons",
+ "syscons versions prior to 1.0 require",
+ "either the",
+ "server's stdin be a VT",
+ "or the use of the vtxx server option");
+ }
+ }
+ from = X_PROBED;
+ }
+
+ close(fd);
+#ifndef __OpenBSD__
+ sprintf(vtname, "/dev/ttyv%01x", xf86Info.vtno - 1);
+#else
+ sprintf(vtname, "/dev/ttyC%01x", xf86Info.vtno - 1);
+#endif
+ if ((fd = open(vtname, SYSCONS_CONSOLE_MODE, 0)) < 0)
+ {
+ FatalError("xf86OpenSyscons: Cannot open %s (%s)",
+ vtname, strerror(errno));
+ }
+ if (ioctl(fd, VT_GETMODE, &vtmode) < 0)
+ {
+ FatalError("xf86OpenSyscons: VT_GETMODE failed");
+ }
+ xf86Info.consType = SYSCONS;
+ xf86Msg(X_PROBED, "Using syscons driver with X support");
+ if (syscons_version >= 0x100)
+ {
+ xf86ErrorF(" (version %ld.%ld)\n", syscons_version >> 8,
+ syscons_version & 0xFF);
+ }
+ else
+ {
+ xf86ErrorF(" (version 0.x)\n");
+ }
+ xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
+ }
+ else
+ {
+ /* VT_GETMODE failed, probably not syscons */
+ close(fd);
+ fd = -1;
+ }
+ }
+ return fd;
+}
+
+#endif /* SYSCONS_SUPPORT */
+
+
+#ifdef PCVT_SUPPORT
+
+static int
+xf86OpenPcvt()
+{
+ /* This looks much like syscons, since pcvt is API compatible */
+ int fd = -1;
+ vtmode_t vtmode;
+ char vtname[12], *vtprefix;
+ struct stat status;
+ struct pcvtid pcvt_version;
+
+#ifndef __OpenBSD__
+ vtprefix = "/dev/ttyv";
+#else
+ vtprefix = "/dev/ttyC";
+#endif
+
+ fd = open(PCVT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0);
+#ifdef WSCONS_PCVT_COMPAT_CONSOLE_DEV
+ if (fd < 0)
+ {
+ fd = open(WSCONS_PCVT_COMPAT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0);
+ vtprefix = "/dev/ttyE";
+ }
+#endif
+ if (fd >= 0)
+ {
+ if (ioctl(fd, VGAPCVTID, &pcvt_version) >= 0)
+ {
+ if(ioctl(fd, VT_GETMODE, &vtmode) < 0)
+ {
+ FatalError("%s: VT_GETMODE failed\n%s%s\n%s",
+ "xf86OpenPcvt",
+ "Found pcvt driver but X11 seems to be",
+ " not supported.", CHECK_DRIVER_MSG);
+ }
+
+ xf86Info.vtno = VTnum;
+
+ if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0)
+ initialVT = -1;
+
+ if (xf86Info.vtno == -1)
+ {
+ if (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0)
+ {
+ /* No free VTs */
+ xf86Info.vtno = -1;
+ }
+
+ if (xf86Info.vtno == -1)
+ {
+ /*
+ * All VTs are in use. If initialVT was found, use it.
+ * Otherwise, if stdin is a VT, use that one.
+ * XXX stdin is already closed, so this won't work.
+ */
+ if (initialVT != -1)
+ {
+ xf86Info.vtno = initialVT;
+ }
+ else if ((fstat(0, &status) >= 0)
+ && S_ISCHR(status.st_mode)
+ && (ioctl(0, VT_GETMODE, &vtmode) >= 0))
+ {
+ /* stdin is a VT */
+ xf86Info.vtno = minor(status.st_rdev) + 1;
+ }
+ else
+ {
+ FatalError("%s: Cannot find a free VT",
+ "xf86OpenPcvt");
+ }
+ }
+ }
+
+ close(fd);
+ sprintf(vtname, "%s%01x", vtprefix, xf86Info.vtno - 1);
+ if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0)
+ {
+ ErrorF("xf86OpenPcvt: Cannot open %s (%s)",
+ vtname, strerror(errno));
+ xf86Info.vtno = initialVT;
+ sprintf(vtname, "%s%01x", vtprefix, xf86Info.vtno - 1);
+ if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0) {
+ FatalError("xf86OpenPcvt: Cannot open %s (%s)",
+ vtname, strerror(errno));
+ }
+ }
+ if (ioctl(fd, VT_GETMODE, &vtmode) < 0)
+ {
+ FatalError("xf86OpenPcvt: VT_GETMODE failed");
+ }
+ xf86Info.consType = PCVT;
+#ifdef WSCONS_SUPPORT
+ xf86Msg(X_PROBED,
+ "Using wscons driver on %s in pcvt compatibility mode "
+ "(version %d.%d)\n", vtname,
+ pcvt_version.rmajor, pcvt_version.rminor);
+#else
+ xf86Msg(X_PROBED, "Using pcvt driver (version %d.%d)\n",
+ pcvt_version.rmajor, pcvt_version.rminor);
+#endif
+ }
+ else
+ {
+ /* Not pcvt */
+ close(fd);
+ fd = -1;
+ }
+ }
+ return fd;
+}
+
+#endif /* PCVT_SUPPORT */
+
+#ifdef WSCONS_SUPPORT
+
+static int
+xf86OpenWScons()
+{
+ int fd = -1;
+ int mode = WSDISPLAYIO_MODE_MAPPED;
+ int i;
+ char ttyname[16];
+
+ /* XXX Is this ok? */
+ for (i = 0; i < 8; i++) {
+#if defined(__NetBSD__)
+ sprintf(ttyname, "/dev/ttyE%d", i);
+#elif defined(__OpenBSD__)
+ sprintf(ttyname, "/dev/ttyC%x", i);
+#endif
+ if ((fd = open(ttyname, 2)) != -1)
+ break;
+ }
+ if (fd != -1) {
+ if (ioctl(fd, WSDISPLAYIO_SMODE, &mode) < 0) {
+ FatalError("%s: WSDISPLAYIO_MODE_MAPPED failed (%s)\n%s",
+ "xf86OpenConsole", strerror(errno),
+ CHECK_DRIVER_MSG);
+ }
+ xf86Info.consType = WSCONS;
+ xf86Msg(X_PROBED, "Using wscons driver\n");
+ }
+ return fd;
+}
+
+#endif /* WSCONS_SUPPORT */
+
+void
+xf86CloseConsole()
+{
+#if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT)
+ struct vt_mode VT;
+#endif
+
+ if (ShareVTs) return;
+
+ switch (xf86Info.consType)
+ {
+#ifdef PCCONS_SUPPORT
+ case PCCONS:
+ ioctl (xf86Info.consoleFd, CONSOLE_X_MODE_OFF, 0);
+ break;
+#endif /* PCCONS_SUPPORT */
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ case SYSCONS:
+ case PCVT:
+ ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); /* Back to text mode */
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
+ {
+ VT.mode = VT_AUTO;
+ ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* dflt vt handling */
+ }
+#if !defined(OpenBSD) && !defined(USE_DEV_IO) && !defined(USE_I386_IOPL)
+ if (ioctl(xf86Info.consoleFd, KDDISABIO, 0) < 0)
+ {
+ xf86FatalError("xf86CloseConsole: KDDISABIO failed (%s)",
+ strerror(errno));
+ }
+#endif
+ if (initialVT != -1)
+ ioctl(xf86Info.consoleFd, VT_ACTIVATE, initialVT);
+ break;
+#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
+#ifdef WSCONS_SUPPORT
+ case WSCONS:
+ {
+ int mode = WSDISPLAYIO_MODE_EMUL;
+ ioctl(xf86Info.screenFd, WSDISPLAYIO_SMODE, &mode);
+ break;
+ }
+#endif
+ }
+
+ if (xf86Info.screenFd != xf86Info.consoleFd)
+ {
+ close(xf86Info.screenFd);
+ close(xf86Info.consoleFd);
+ if ((xf86Info.consoleFd = open("/dev/console",O_RDONLY,0)) <0)
+ {
+ xf86FatalError("xf86CloseConsole: Cannot open /dev/console (%s)",
+ strerror(errno));
+ }
+ }
+ close(xf86Info.consoleFd);
+ if (devConsoleFd >= 0)
+ close(devConsoleFd);
+ return;
+}
+
+int
+xf86ProcessArgument(int argc, char *argv[], int i)
+{
+ /*
+ * Keep server from detaching from controlling tty. This is useful
+ * when debugging (so the server can receive keyboard signals.
+ */
+ if (!strcmp(argv[i], "-keeptty"))
+ {
+ KeepTty = TRUE;
+ return 1;
+ }
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ if (!strcmp(argv[i], "-sharevts"))
+ {
+ ShareVTs = TRUE;
+ return 1;
+ }
+ if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
+ {
+ if (sscanf(argv[i], "vt%2d", &VTnum) == 0 ||
+ VTnum < 1 || VTnum > 12)
+ {
+ UseMsg();
+ VTnum = -1;
+ return 0;
+ }
+ return 1;
+ }
+#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
+ return 0;
+}
+
+void
+xf86UseMsg()
+{
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ ErrorF("vtXX use the specified VT number (1-12)\n");
+ ErrorF("-sharevts share VTs with another X server\n");
+#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
+ ErrorF("-keeptty ");
+ ErrorF("don't detach controlling tty (for debugging only)\n");
+ return;
+}
diff --git a/xorg-server/hw/xfree86/os-support/linux/lnx_init.c b/xorg-server/hw/xfree86/os-support/linux/lnx_init.c
index 77dfb2f16..647c05c3a 100644
--- a/xorg-server/hw/xfree86/os-support/linux/lnx_init.c
+++ b/xorg-server/hw/xfree86/os-support/linux/lnx_init.c
@@ -1,345 +1,345 @@
-/*
- * Copyright 1992 by Orest Zborowski <obz@Kodak.com>
- * Copyright 1993 by David Wexelblat <dwex@goblin.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 names of Orest Zborowski and David Wexelblat
- * not be used in advertising or publicity pertaining to distribution of
- * the software without specific, written prior permission. Orest Zborowski
- * and David Wexelblat make no representations about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- *
- * OREST ZBOROWSKI AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD
- * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT 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.
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xmd.h>
-
-#include "compiler.h"
-
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-
-#include <sys/stat.h>
-
-static Bool KeepTty = FALSE;
-static Bool VTSwitch = TRUE;
-static Bool ShareVTs = FALSE;
-static int activeVT = -1;
-
-static char vtname[11];
-static struct termios tty_attr; /* tty state to restore */
-static int tty_mode; /* kbd mode to restore */
-
-static void *console_handler;
-
-static void
-drain_console(int fd, void *closure)
-{
- errno = 0;
- if (tcflush(fd, TCIOFLUSH) == -1 && errno == EIO) {
- xf86RemoveGeneralHandler(console_handler);
- console_handler = NULL;
- }
-}
-
-static void
-switch_to(int vt, const char *from)
-{
- int ret;
-
- SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_ACTIVATE, vt));
- if (ret < 0)
- FatalError("%s: VT_ACTIVATE failed: %s\n", from, strerror(errno));
-
- SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_WAITACTIVE, vt));
- if (ret < 0)
- FatalError("%s: VT_WAITACTIVE failed: %s\n", from, strerror(errno));
-}
-
-void
-xf86OpenConsole(void)
-{
- int i, fd = -1, ret;
- struct vt_mode VT;
- struct vt_stat vts;
- MessageType from = X_PROBED;
- char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
- char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
-
- if (serverGeneration == 1) {
-
- /* when KeepTty check if we're run with euid==0 */
- if (KeepTty && geteuid() != 0)
- FatalError("xf86OpenConsole:"
- " Server must be suid root for option \"KeepTTY\"\n");
-
- /*
- * setup the virtual terminal manager
- */
- if (xf86Info.vtno != -1) {
- from = X_CMDLINE;
- } else {
-
- i=0;
- while (tty0[i] != NULL) {
- if ((fd = open(tty0[i],O_WRONLY,0)) >= 0)
- break;
- i++;
- }
-
- if (fd < 0)
- FatalError(
- "xf86OpenConsole: Cannot open /dev/tty0 (%s)\n",
- strerror(errno));
-
- if (ShareVTs)
- {
- SYSCALL(ret = ioctl(fd, VT_GETSTATE, &vts));
- if (ret < 0)
- FatalError("xf86OpenConsole: Cannot find the current"
- " VT (%s)\n", strerror(errno));
- xf86Info.vtno = vts.v_active;
- } else {
- SYSCALL(ret = ioctl(fd, VT_OPENQRY, &xf86Info.vtno));
- if (ret < 0)
- FatalError("xf86OpenConsole: Cannot find a free VT: "
- "%s\n", strerror(errno));
- if (xf86Info.vtno == -1)
- FatalError("xf86OpenConsole: Cannot find a free VT\n");
- }
- close(fd);
- }
-
- xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
-
- if (!KeepTty) {
- pid_t ppid = getppid();
- pid_t ppgid;
- ppgid = getpgid(ppid);
-
- /*
- * change to parent process group that pgid != pid so
- * that setsid() doesn't fail and we become process
- * group leader
- */
- if (setpgid(0,ppgid) < 0)
- xf86Msg(X_WARNING, "xf86OpenConsole: setpgid failed: %s\n",
- strerror(errno));
-
- /* become process group leader */
- if ((setsid() < 0))
- xf86Msg(X_WARNING, "xf86OpenConsole: setsid failed: %s\n",
- strerror(errno));
- }
-
- i=0;
- while (vcs[i] != NULL) {
- sprintf(vtname, vcs[i], xf86Info.vtno); /* /dev/tty1-64 */
- if ((xf86Info.consoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) >= 0)
- break;
- i++;
- }
-
- if (xf86Info.consoleFd < 0)
- FatalError("xf86OpenConsole: Cannot open virtual console"
- " %d (%s)\n", xf86Info.vtno, strerror(errno));
-
- /*
- * Linux doesn't switch to an active vt after the last close of a vt,
- * so we do this ourselves by remembering which is active now.
- */
- SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_GETSTATE, &vts));
- if (ret < 0)
- xf86Msg(X_WARNING,"xf86OpenConsole: VT_GETSTATE failed: %s\n",
- strerror(errno));
- else
- activeVT = vts.v_active;
-
-#if 0
- if (!KeepTty) {
- /*
- * Detach from the controlling tty to avoid char loss
- */
- if ((i = open("/dev/tty",O_RDWR)) >= 0) {
- SYSCALL(ioctl(i, TIOCNOTTY, 0));
- close(i);
- }
- }
-#endif
-
- if (!ShareVTs)
- {
- struct termios nTty;
-
- /*
- * now get the VT. This _must_ succeed, or else fail completely.
- */
- switch_to(xf86Info.vtno, "xf86OpenConsole");
-
- SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_GETMODE, &VT));
- if (ret < 0)
- FatalError("xf86OpenConsole: VT_GETMODE failed %s\n",
- strerror(errno));
-
- signal(SIGUSR1, xf86VTRequest);
-
- VT.mode = VT_PROCESS;
- VT.relsig = SIGUSR1;
- VT.acqsig = SIGUSR1;
-
- SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_SETMODE, &VT));
- if (ret < 0)
- FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed: %s\n",
- strerror(errno));
-
- SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS));
- if (ret < 0)
- FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed %s\n",
- strerror(errno));
-
- tcgetattr(xf86Info.consoleFd, &tty_attr);
- SYSCALL(ioctl(xf86Info.consoleFd, KDGKBMODE, &tty_mode));
-
- SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSKBMODE, K_RAW));
- if (ret < 0)
- FatalError("xf86OpenConsole: KDSKBMODE K_RAW failed %s\n",
- strerror(errno));
-
- nTty = tty_attr;
- nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
- nTty.c_oflag = 0;
- nTty.c_cflag = CREAD | CS8;
- nTty.c_lflag = 0;
- nTty.c_cc[VTIME]=0;
- nTty.c_cc[VMIN]=1;
- cfsetispeed(&nTty, 9600);
- cfsetospeed(&nTty, 9600);
- tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty);
-
- /* need to keep the buffer clean, else the kernel gets angry */
- xf86SetConsoleHandler(drain_console, NULL);
-
- /* we really should have a InitOSInputDevices() function instead
- * of Init?$#*&Device(). So I just place it here */
- }
- } else { /* serverGeneration != 1 */
- if (!ShareVTs && VTSwitch)
- {
- /* now get the VT */
- switch_to(xf86Info.vtno, "xf86OpenConsole");
- }
- }
-}
-
-void
-xf86CloseConsole(void)
-{
- struct vt_mode VT;
- int ret;
-
- if (ShareVTs) {
- close(xf86Info.consoleFd);
- return;
- }
-
- if (console_handler) {
- xf86RemoveGeneralHandler(console_handler);
- console_handler = NULL;
- };
-
- /* Back to text mode ... */
- SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT));
- if (ret < 0)
- xf86Msg(X_WARNING, "xf86CloseConsole: KDSETMODE failed: %s\n",
- strerror(errno));
-
- SYSCALL(ioctl(xf86Info.consoleFd, KDSKBMODE, tty_mode));
- tcsetattr(xf86Info.consoleFd, TCSANOW, &tty_attr);
-
- SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_GETMODE, &VT));
- if (ret < 0)
- xf86Msg(X_WARNING, "xf86CloseConsole: VT_GETMODE failed: %s\n",
- strerror(errno));
- else {
- /* set dflt vt handling */
- VT.mode = VT_AUTO;
- SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_SETMODE, &VT));
- if (ret < 0)
- xf86Msg(X_WARNING, "xf86CloseConsole: VT_SETMODE failed: %s\n",
- strerror(errno));
- }
-
- if (VTSwitch)
- {
- /*
- * Perform a switch back to the active VT when we were started
- */
- if (activeVT >= 0) {
- switch_to(activeVT, "xf86CloseConsole");
- activeVT = -1;
- }
- }
- close(xf86Info.consoleFd); /* make the vt-manager happy */
-}
-
-int
-xf86ProcessArgument(int argc, char *argv[], int i)
-{
- /*
- * Keep server from detaching from controlling tty. This is useful
- * when debugging (so the server can receive keyboard signals.
- */
- if (!strcmp(argv[i], "-keeptty"))
- {
- KeepTty = TRUE;
- return 1;
- }
- if (!strcmp(argv[i], "-novtswitch"))
- {
- VTSwitch = FALSE;
- return 1;
- }
- if (!strcmp(argv[i], "-sharevts"))
- {
- ShareVTs = TRUE;
- return 1;
- }
- if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
- {
- if (sscanf(argv[i], "vt%2d", &xf86Info.vtno) == 0)
- {
- UseMsg();
- xf86Info.vtno = -1;
- return 0;
- }
- return 1;
- }
- return 0;
-}
-
-void
-xf86UseMsg(void)
-{
- ErrorF("vtXX use the specified VT number\n");
- ErrorF("-keeptty ");
- ErrorF("don't detach controlling tty (for debugging only)\n");
- ErrorF("-novtswitch don't immediately switch to new VT\n");
- ErrorF("-sharevts share VTs with another X server\n");
-}
+/*
+ * Copyright 1992 by Orest Zborowski <obz@Kodak.com>
+ * Copyright 1993 by David Wexelblat <dwex@goblin.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 names of Orest Zborowski and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Orest Zborowski
+ * and David Wexelblat make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * OREST ZBOROWSKI AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT 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.
+ *
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#include <sys/stat.h>
+
+static Bool KeepTty = FALSE;
+static Bool VTSwitch = TRUE;
+static Bool ShareVTs = FALSE;
+static int activeVT = -1;
+
+static char vtname[11];
+static struct termios tty_attr; /* tty state to restore */
+static int tty_mode; /* kbd mode to restore */
+
+static void *console_handler;
+
+static void
+drain_console(int fd, void *closure)
+{
+ errno = 0;
+ if (tcflush(fd, TCIOFLUSH) == -1 && errno == EIO) {
+ xf86RemoveGeneralHandler(console_handler);
+ console_handler = NULL;
+ }
+}
+
+static void
+switch_to(int vt, const char *from)
+{
+ int ret;
+
+ SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_ACTIVATE, vt));
+ if (ret < 0)
+ FatalError("%s: VT_ACTIVATE failed: %s\n", from, strerror(errno));
+
+ SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_WAITACTIVE, vt));
+ if (ret < 0)
+ FatalError("%s: VT_WAITACTIVE failed: %s\n", from, strerror(errno));
+}
+
+void
+xf86OpenConsole(void)
+{
+ int i, fd = -1, ret;
+ struct vt_mode VT;
+ struct vt_stat vts;
+ MessageType from = X_PROBED;
+ char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
+ char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
+
+ if (serverGeneration == 1) {
+
+ /* when KeepTty check if we're run with euid==0 */
+ if (KeepTty && geteuid() != 0)
+ FatalError("xf86OpenConsole:"
+ " Server must be suid root for option \"KeepTTY\"\n");
+
+ /*
+ * setup the virtual terminal manager
+ */
+ if (xf86Info.vtno != -1) {
+ from = X_CMDLINE;
+ } else {
+
+ i=0;
+ while (tty0[i] != NULL) {
+ if ((fd = open(tty0[i],O_WRONLY,0)) >= 0)
+ break;
+ i++;
+ }
+
+ if (fd < 0)
+ FatalError(
+ "xf86OpenConsole: Cannot open /dev/tty0 (%s)\n",
+ strerror(errno));
+
+ if (ShareVTs)
+ {
+ SYSCALL(ret = ioctl(fd, VT_GETSTATE, &vts));
+ if (ret < 0)
+ FatalError("xf86OpenConsole: Cannot find the current"
+ " VT (%s)\n", strerror(errno));
+ xf86Info.vtno = vts.v_active;
+ } else {
+ SYSCALL(ret = ioctl(fd, VT_OPENQRY, &xf86Info.vtno));
+ if (ret < 0)
+ FatalError("xf86OpenConsole: Cannot find a free VT: "
+ "%s\n", strerror(errno));
+ if (xf86Info.vtno == -1)
+ FatalError("xf86OpenConsole: Cannot find a free VT\n");
+ }
+ close(fd);
+ }
+
+ xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
+
+ if (!KeepTty) {
+ pid_t ppid = getppid();
+ pid_t ppgid;
+ ppgid = getpgid(ppid);
+
+ /*
+ * change to parent process group that pgid != pid so
+ * that setsid() doesn't fail and we become process
+ * group leader
+ */
+ if (setpgid(0,ppgid) < 0)
+ xf86Msg(X_WARNING, "xf86OpenConsole: setpgid failed: %s\n",
+ strerror(errno));
+
+ /* become process group leader */
+ if ((setsid() < 0))
+ xf86Msg(X_WARNING, "xf86OpenConsole: setsid failed: %s\n",
+ strerror(errno));
+ }
+
+ i=0;
+ while (vcs[i] != NULL) {
+ sprintf(vtname, vcs[i], xf86Info.vtno); /* /dev/tty1-64 */
+ if ((xf86Info.consoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) >= 0)
+ break;
+ i++;
+ }
+
+ if (xf86Info.consoleFd < 0)
+ FatalError("xf86OpenConsole: Cannot open virtual console"
+ " %d (%s)\n", xf86Info.vtno, strerror(errno));
+
+ /*
+ * Linux doesn't switch to an active vt after the last close of a vt,
+ * so we do this ourselves by remembering which is active now.
+ */
+ SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_GETSTATE, &vts));
+ if (ret < 0)
+ xf86Msg(X_WARNING,"xf86OpenConsole: VT_GETSTATE failed: %s\n",
+ strerror(errno));
+ else
+ activeVT = vts.v_active;
+
+#if 0
+ if (!KeepTty) {
+ /*
+ * Detach from the controlling tty to avoid char loss
+ */
+ if ((i = open("/dev/tty",O_RDWR)) >= 0) {
+ SYSCALL(ioctl(i, TIOCNOTTY, 0));
+ close(i);
+ }
+ }
+#endif
+
+ if (!ShareVTs)
+ {
+ struct termios nTty;
+
+ /*
+ * now get the VT. This _must_ succeed, or else fail completely.
+ */
+ switch_to(xf86Info.vtno, "xf86OpenConsole");
+
+ SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_GETMODE, &VT));
+ if (ret < 0)
+ FatalError("xf86OpenConsole: VT_GETMODE failed %s\n",
+ strerror(errno));
+
+ signal(SIGUSR1, xf86VTRequest);
+
+ VT.mode = VT_PROCESS;
+ VT.relsig = SIGUSR1;
+ VT.acqsig = SIGUSR1;
+
+ SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_SETMODE, &VT));
+ if (ret < 0)
+ FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed: %s\n",
+ strerror(errno));
+
+ SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS));
+ if (ret < 0)
+ FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed %s\n",
+ strerror(errno));
+
+ tcgetattr(xf86Info.consoleFd, &tty_attr);
+ SYSCALL(ioctl(xf86Info.consoleFd, KDGKBMODE, &tty_mode));
+
+ SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSKBMODE, K_RAW));
+ if (ret < 0)
+ FatalError("xf86OpenConsole: KDSKBMODE K_RAW failed %s\n",
+ strerror(errno));
+
+ nTty = tty_attr;
+ nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
+ nTty.c_oflag = 0;
+ nTty.c_cflag = CREAD | CS8;
+ nTty.c_lflag = 0;
+ nTty.c_cc[VTIME]=0;
+ nTty.c_cc[VMIN]=1;
+ cfsetispeed(&nTty, 9600);
+ cfsetospeed(&nTty, 9600);
+ tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty);
+
+ /* need to keep the buffer clean, else the kernel gets angry */
+ xf86SetConsoleHandler(drain_console, NULL);
+
+ /* we really should have a InitOSInputDevices() function instead
+ * of Init?$#*&Device(). So I just place it here */
+ }
+ } else { /* serverGeneration != 1 */
+ if (!ShareVTs && VTSwitch)
+ {
+ /* now get the VT */
+ switch_to(xf86Info.vtno, "xf86OpenConsole");
+ }
+ }
+}
+
+void
+xf86CloseConsole(void)
+{
+ struct vt_mode VT;
+ int ret;
+
+ if (ShareVTs) {
+ close(xf86Info.consoleFd);
+ return;
+ }
+
+ if (console_handler) {
+ xf86RemoveGeneralHandler(console_handler);
+ console_handler = NULL;
+ };
+
+ /* Back to text mode ... */
+ SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT));
+ if (ret < 0)
+ xf86Msg(X_WARNING, "xf86CloseConsole: KDSETMODE failed: %s\n",
+ strerror(errno));
+
+ SYSCALL(ioctl(xf86Info.consoleFd, KDSKBMODE, tty_mode));
+ tcsetattr(xf86Info.consoleFd, TCSANOW, &tty_attr);
+
+ SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_GETMODE, &VT));
+ if (ret < 0)
+ xf86Msg(X_WARNING, "xf86CloseConsole: VT_GETMODE failed: %s\n",
+ strerror(errno));
+ else {
+ /* set dflt vt handling */
+ VT.mode = VT_AUTO;
+ SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_SETMODE, &VT));
+ if (ret < 0)
+ xf86Msg(X_WARNING, "xf86CloseConsole: VT_SETMODE failed: %s\n",
+ strerror(errno));
+ }
+
+ if (VTSwitch)
+ {
+ /*
+ * Perform a switch back to the active VT when we were started
+ */
+ if (activeVT >= 0) {
+ switch_to(activeVT, "xf86CloseConsole");
+ activeVT = -1;
+ }
+ }
+ close(xf86Info.consoleFd); /* make the vt-manager happy */
+}
+
+int
+xf86ProcessArgument(int argc, char *argv[], int i)
+{
+ /*
+ * Keep server from detaching from controlling tty. This is useful
+ * when debugging (so the server can receive keyboard signals.
+ */
+ if (!strcmp(argv[i], "-keeptty"))
+ {
+ KeepTty = TRUE;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-novtswitch"))
+ {
+ VTSwitch = FALSE;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-sharevts"))
+ {
+ ShareVTs = TRUE;
+ return 1;
+ }
+ if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
+ {
+ if (sscanf(argv[i], "vt%2d", &xf86Info.vtno) == 0)
+ {
+ UseMsg();
+ xf86Info.vtno = -1;
+ return 0;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+void
+xf86UseMsg(void)
+{
+ ErrorF("vtXX use the specified VT number\n");
+ ErrorF("-keeptty ");
+ ErrorF("don't detach controlling tty (for debugging only)\n");
+ ErrorF("-novtswitch don't immediately switch to new VT\n");
+ ErrorF("-sharevts share VTs with another X server\n");
+}
diff --git a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
index 24c91cc37..6eab1a3dd 100644
--- a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
+++ b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
@@ -1,475 +1,475 @@
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86CursorPriv.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-
-/* FIXME: This was added with the ABI change of the miPointerSpriteFuncs for
- * MPX.
- * inputInfo is needed to pass the core pointer as the default argument into
- * the cursor functions.
- *
- * Externing inputInfo is not the nice way to do it but it works.
- */
-#include "inputstr.h"
-extern InputInfo inputInfo;
-
-DevPrivateKeyRec xf86CursorScreenKeyRec;
-
-/* sprite functions */
-
-static Bool xf86CursorRealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
-static Bool xf86CursorUnrealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
-static void xf86CursorSetCursor(DeviceIntPtr, ScreenPtr, CursorPtr, int, int);
-static void xf86CursorMoveCursor(DeviceIntPtr, ScreenPtr, int, int);
-static Bool xf86DeviceCursorInitialize(DeviceIntPtr, ScreenPtr);
-static void xf86DeviceCursorCleanup(DeviceIntPtr, ScreenPtr);
-
-static miPointerSpriteFuncRec xf86CursorSpriteFuncs = {
- xf86CursorRealizeCursor,
- xf86CursorUnrealizeCursor,
- xf86CursorSetCursor,
- xf86CursorMoveCursor,
- xf86DeviceCursorInitialize,
- xf86DeviceCursorCleanup
-};
-
-/* Screen functions */
-
-static void xf86CursorInstallColormap(ColormapPtr);
-static void xf86CursorRecolorCursor(DeviceIntPtr pDev, ScreenPtr, CursorPtr, Bool);
-static Bool xf86CursorCloseScreen(int, ScreenPtr);
-static void xf86CursorQueryBestSize(int, unsigned short*, unsigned short*,
- ScreenPtr);
-
-/* ScrnInfoRec functions */
-
-static void xf86CursorEnableDisableFBAccess(int, Bool);
-static Bool xf86CursorSwitchMode(int, DisplayModePtr,int);
-
-Bool
-xf86InitCursor(
- ScreenPtr pScreen,
- xf86CursorInfoPtr infoPtr
-)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CursorScreenPtr ScreenPriv;
- miPointerScreenPtr PointPriv;
-
- if (!xf86InitHardwareCursor(pScreen, infoPtr))
- return FALSE;
-
- if (!dixRegisterPrivateKey(&xf86CursorScreenKeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
-
- ScreenPriv = calloc(1, sizeof(xf86CursorScreenRec));
- if (!ScreenPriv)
- return FALSE;
-
- dixSetPrivate(&pScreen->devPrivates, xf86CursorScreenKey, ScreenPriv);
-
- ScreenPriv->SWCursor = TRUE;
- ScreenPriv->isUp = FALSE;
- ScreenPriv->CurrentCursor = NULL;
- ScreenPriv->CursorInfoPtr = infoPtr;
- ScreenPriv->PalettedCursor = FALSE;
- ScreenPriv->pInstalledMap = NULL;
-
- ScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xf86CursorCloseScreen;
- ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
- pScreen->QueryBestSize = xf86CursorQueryBestSize;
- ScreenPriv->RecolorCursor = pScreen->RecolorCursor;
- pScreen->RecolorCursor = xf86CursorRecolorCursor;
-
- if ((infoPtr->pScrn->bitsPerPixel == 8) &&
- !(infoPtr->Flags & HARDWARE_CURSOR_TRUECOLOR_AT_8BPP)) {
- ScreenPriv->InstallColormap = pScreen->InstallColormap;
- pScreen->InstallColormap = xf86CursorInstallColormap;
- ScreenPriv->PalettedCursor = TRUE;
- }
-
- PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
-
- ScreenPriv->showTransparent = PointPriv->showTransparent;
- if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT)
- PointPriv->showTransparent = TRUE;
- else
- PointPriv->showTransparent = FALSE;
- ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
- PointPriv->spriteFuncs = &xf86CursorSpriteFuncs;
-
- ScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess;
- ScreenPriv->SwitchMode = pScrn->SwitchMode;
-
- ScreenPriv->ForceHWCursorCount = 0;
- ScreenPriv->HWCursorForced = FALSE;
-
- pScrn->EnableDisableFBAccess = xf86CursorEnableDisableFBAccess;
- if (pScrn->SwitchMode)
- pScrn->SwitchMode = xf86CursorSwitchMode;
-
- return TRUE;
-}
-
-/***** Screen functions *****/
-
-static Bool
-xf86CursorCloseScreen(int i, ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, miPointerScreenKey);
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (ScreenPriv->isUp && pScrn->vtSema)
- xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
-
- if (ScreenPriv->CurrentCursor)
- FreeCursor(ScreenPriv->CurrentCursor, None);
-
- pScreen->CloseScreen = ScreenPriv->CloseScreen;
- pScreen->QueryBestSize = ScreenPriv->QueryBestSize;
- pScreen->RecolorCursor = ScreenPriv->RecolorCursor;
- if (ScreenPriv->InstallColormap)
- pScreen->InstallColormap = ScreenPriv->InstallColormap;
-
- PointPriv->spriteFuncs = ScreenPriv->spriteFuncs;
- PointPriv->showTransparent = ScreenPriv->showTransparent;
-
- pScrn->EnableDisableFBAccess = ScreenPriv->EnableDisableFBAccess;
- pScrn->SwitchMode = ScreenPriv->SwitchMode;
-
- free(ScreenPriv->transparentData);
- free(ScreenPriv);
-
- return (*pScreen->CloseScreen)(i, pScreen);
-}
-
-static void
-xf86CursorQueryBestSize(
- int class,
- unsigned short *width,
- unsigned short *height,
- ScreenPtr pScreen)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (class == CursorShape) {
- if(*width > ScreenPriv->CursorInfoPtr->MaxWidth)
- *width = ScreenPriv->CursorInfoPtr->MaxWidth;
- if(*height > ScreenPriv->CursorInfoPtr->MaxHeight)
- *height = ScreenPriv->CursorInfoPtr->MaxHeight;
- } else
- (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
-}
-
-static void
-xf86CursorInstallColormap(ColormapPtr pMap)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pMap->pScreen->devPrivates, xf86CursorScreenKey);
-
- ScreenPriv->pInstalledMap = pMap;
-
- (*ScreenPriv->InstallColormap)(pMap);
-}
-
-static void
-xf86CursorRecolorCursor(
- DeviceIntPtr pDev,
- ScreenPtr pScreen,
- CursorPtr pCurs,
- Bool displayed)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (!displayed)
- return;
-
- if (ScreenPriv->SWCursor)
- (*ScreenPriv->RecolorCursor)(pDev, pScreen, pCurs, displayed);
- else
- xf86RecolorCursor(pScreen, pCurs, displayed);
-}
-
-/***** ScrnInfoRec functions *********/
-
-static void
-xf86CursorEnableDisableFBAccess(
- int index,
- Bool enable)
-{
- DeviceIntPtr pDev = inputInfo.pointer;
-
- ScreenPtr pScreen = screenInfo.screens[index];
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (!enable && ScreenPriv->CurrentCursor != NullCursor) {
- CursorPtr currentCursor = ScreenPriv->CurrentCursor;
- xf86CursorSetCursor(pDev, pScreen, NullCursor, ScreenPriv->x,
- ScreenPriv->y);
- ScreenPriv->isUp = FALSE;
- ScreenPriv->SWCursor = TRUE;
- ScreenPriv->SavedCursor = currentCursor;
- }
-
- if (ScreenPriv->EnableDisableFBAccess)
- (*ScreenPriv->EnableDisableFBAccess)(index, enable);
-
- if (enable && ScreenPriv->SavedCursor)
- {
- /*
- * Re-set current cursor so drivers can react to FB access having been
- * temporarily disabled.
- */
- xf86CursorSetCursor(pDev, pScreen, ScreenPriv->SavedCursor,
- ScreenPriv->x, ScreenPriv->y);
- ScreenPriv->SavedCursor = NULL;
- }
-}
-
-static Bool
-xf86CursorSwitchMode(int index, DisplayModePtr mode, int flags)
-{
- Bool ret;
- ScreenPtr pScreen = screenInfo.screens[index];
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (ScreenPriv->isUp) {
- xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
- ScreenPriv->isUp = FALSE;
- }
-
- ret = (*ScreenPriv->SwitchMode)(index, mode, flags);
-
- /*
- * Cannot restore cursor here because the new frame[XY][01] haven't been
- * calculated yet. However, because the hardware cursor was removed above,
- * ensure the cursor is repainted by miPointerWarpCursor().
- */
- ScreenPriv->CursorToRestore = ScreenPriv->CurrentCursor;
- miPointerSetWaitForUpdate(pScreen, FALSE); /* Force cursor repaint */
-
- return ret;
-}
-
-/****** miPointerSpriteFunctions *******/
-
-static Bool
-xf86CursorRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (pCurs->refcnt <= 1)
- dixSetPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen), NULL);
-
- return (*ScreenPriv->spriteFuncs->RealizeCursor)(pDev, pScreen, pCurs);
-}
-
-static Bool
-xf86CursorUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
- CursorPtr pCurs)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (pCurs->refcnt <= 1) {
- free(dixLookupPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen)));
- dixSetPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen), NULL);
- }
-
- return (*ScreenPriv->spriteFuncs->UnrealizeCursor)(pDev, pScreen, pCurs);
-}
-
-static void
-xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
- int x, int y)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
- xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
-
- if (pCurs == NullCursor) { /* means we're supposed to remove the cursor */
- if (ScreenPriv->SWCursor ||
- !(GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer))
- (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y);
- else if (ScreenPriv->isUp) {
- xf86SetCursor(pScreen, NullCursor, x, y);
- ScreenPriv->isUp = FALSE;
- }
- if (ScreenPriv->CurrentCursor)
- FreeCursor(ScreenPriv->CurrentCursor, None);
- ScreenPriv->CurrentCursor = NullCursor;
- return;
- }
-
- /* only update for VCP, otherwise we get cursor jumps when removing a
- sprite. The second cursor is never HW rendered anyway. */
- if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer)
- {
- pCurs->refcnt++;
- if (ScreenPriv->CurrentCursor)
- FreeCursor(ScreenPriv->CurrentCursor, None);
- ScreenPriv->CurrentCursor = pCurs;
- ScreenPriv->x = x;
- ScreenPriv->y = y;
- ScreenPriv->CursorToRestore = NULL;
- ScreenPriv->HotX = pCurs->bits->xhot;
- ScreenPriv->HotY = pCurs->bits->yhot;
-
- if (!infoPtr->pScrn->vtSema)
- ScreenPriv->SavedCursor = pCurs;
-
- if (infoPtr->pScrn->vtSema && (ScreenPriv->ForceHWCursorCount || ((
-#ifdef ARGB_CURSOR
- pCurs->bits->argb && infoPtr->UseHWCursorARGB &&
- (*infoPtr->UseHWCursorARGB) (pScreen, pCurs) ) || (
- pCurs->bits->argb == 0 &&
-#endif
- (pCurs->bits->height <= infoPtr->MaxHeight) &&
- (pCurs->bits->width <= infoPtr->MaxWidth) &&
- (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor)(pScreen, pCurs))))))
- {
-
- if (ScreenPriv->SWCursor) /* remove the SW cursor */
- (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y);
-
- xf86SetCursor(pScreen, pCurs, x, y);
- ScreenPriv->SWCursor = FALSE;
- ScreenPriv->isUp = TRUE;
-
- miPointerSetWaitForUpdate(pScreen, !infoPtr->pScrn->silkenMouse);
- return;
- }
-
- miPointerSetWaitForUpdate(pScreen, TRUE);
-
- if (ScreenPriv->isUp) {
- /* Remove the HW cursor, or make it transparent */
- if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT) {
- xf86SetTransparentCursor(pScreen);
- } else {
- xf86SetCursor(pScreen, NullCursor, x, y);
- ScreenPriv->isUp = FALSE;
- }
- }
-
- if (!ScreenPriv->SWCursor)
- ScreenPriv->SWCursor = TRUE;
-
- }
-
- if (pCurs->bits->emptyMask && !ScreenPriv->showTransparent)
- pCurs = NullCursor;
-
- (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, pCurs, x, y);
-}
-
-static void
-xf86CursorMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- /* only update coordinate state for first sprite, otherwise we get jumps
- when removing a sprite. The second sprite is never HW rendered anyway */
- if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer)
- {
- ScreenPriv->x = x;
- ScreenPriv->y = y;
-
- if (ScreenPriv->CursorToRestore)
- xf86CursorSetCursor(pDev, pScreen, ScreenPriv->CursorToRestore, x, y);
- else if (ScreenPriv->SWCursor)
- (*ScreenPriv->spriteFuncs->MoveCursor)(pDev, pScreen, x, y);
- else if (ScreenPriv->isUp)
- xf86MoveCursor(pScreen, x, y);
- } else
- (*ScreenPriv->spriteFuncs->MoveCursor)(pDev, pScreen, x, y);
-}
-
-void
-xf86ForceHWCursor (ScreenPtr pScreen, Bool on)
-{
- DeviceIntPtr pDev = inputInfo.pointer;
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (on)
- {
- if (ScreenPriv->ForceHWCursorCount++ == 0)
- {
- if (ScreenPriv->SWCursor && ScreenPriv->CurrentCursor)
- {
- ScreenPriv->HWCursorForced = TRUE;
- xf86CursorSetCursor (pDev, pScreen, ScreenPriv->CurrentCursor,
- ScreenPriv->x, ScreenPriv->y);
- }
- else
- ScreenPriv->HWCursorForced = FALSE;
- }
- }
- else
- {
- if (--ScreenPriv->ForceHWCursorCount == 0)
- {
- if (ScreenPriv->HWCursorForced && ScreenPriv->CurrentCursor)
- xf86CursorSetCursor (pDev, pScreen, ScreenPriv->CurrentCursor,
- ScreenPriv->x, ScreenPriv->y);
- }
- }
-}
-
-xf86CursorInfoPtr
-xf86CreateCursorInfoRec(void)
-{
- return calloc(1, sizeof(xf86CursorInfoRec));
-}
-
-void
-xf86DestroyCursorInfoRec(xf86CursorInfoPtr infoPtr)
-{
- free(infoPtr);
-}
-
-/**
- * New cursor has been created. Do your initalizations here.
- */
-static Bool
-xf86DeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- int ret;
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- /* Init SW cursor */
- ret = (*ScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen);
-
- return ret;
-}
-
-/**
- * Cursor has been removed. Clean up after yourself.
- */
-static void
-xf86DeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- /* Clean up SW cursor */
- (*ScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
-}
-
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86CursorPriv.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+
+/* FIXME: This was added with the ABI change of the miPointerSpriteFuncs for
+ * MPX.
+ * inputInfo is needed to pass the core pointer as the default argument into
+ * the cursor functions.
+ *
+ * Externing inputInfo is not the nice way to do it but it works.
+ */
+#include "inputstr.h"
+extern InputInfo inputInfo;
+
+DevPrivateKeyRec xf86CursorScreenKeyRec;
+
+/* sprite functions */
+
+static Bool xf86CursorRealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
+static Bool xf86CursorUnrealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
+static void xf86CursorSetCursor(DeviceIntPtr, ScreenPtr, CursorPtr, int, int);
+static void xf86CursorMoveCursor(DeviceIntPtr, ScreenPtr, int, int);
+static Bool xf86DeviceCursorInitialize(DeviceIntPtr, ScreenPtr);
+static void xf86DeviceCursorCleanup(DeviceIntPtr, ScreenPtr);
+
+static miPointerSpriteFuncRec xf86CursorSpriteFuncs = {
+ xf86CursorRealizeCursor,
+ xf86CursorUnrealizeCursor,
+ xf86CursorSetCursor,
+ xf86CursorMoveCursor,
+ xf86DeviceCursorInitialize,
+ xf86DeviceCursorCleanup
+};
+
+/* Screen functions */
+
+static void xf86CursorInstallColormap(ColormapPtr);
+static void xf86CursorRecolorCursor(DeviceIntPtr pDev, ScreenPtr, CursorPtr, Bool);
+static Bool xf86CursorCloseScreen(int, ScreenPtr);
+static void xf86CursorQueryBestSize(int, unsigned short*, unsigned short*,
+ ScreenPtr);
+
+/* ScrnInfoRec functions */
+
+static void xf86CursorEnableDisableFBAccess(int, Bool);
+static Bool xf86CursorSwitchMode(int, DisplayModePtr,int);
+
+Bool
+xf86InitCursor(
+ ScreenPtr pScreen,
+ xf86CursorInfoPtr infoPtr
+)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CursorScreenPtr ScreenPriv;
+ miPointerScreenPtr PointPriv;
+
+ if (!xf86InitHardwareCursor(pScreen, infoPtr))
+ return FALSE;
+
+ if (!dixRegisterPrivateKey(&xf86CursorScreenKeyRec, PRIVATE_SCREEN, 0))
+ return FALSE;
+
+ ScreenPriv = calloc(1, sizeof(xf86CursorScreenRec));
+ if (!ScreenPriv)
+ return FALSE;
+
+ dixSetPrivate(&pScreen->devPrivates, xf86CursorScreenKey, ScreenPriv);
+
+ ScreenPriv->SWCursor = TRUE;
+ ScreenPriv->isUp = FALSE;
+ ScreenPriv->CurrentCursor = NULL;
+ ScreenPriv->CursorInfoPtr = infoPtr;
+ ScreenPriv->PalettedCursor = FALSE;
+ ScreenPriv->pInstalledMap = NULL;
+
+ ScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xf86CursorCloseScreen;
+ ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
+ pScreen->QueryBestSize = xf86CursorQueryBestSize;
+ ScreenPriv->RecolorCursor = pScreen->RecolorCursor;
+ pScreen->RecolorCursor = xf86CursorRecolorCursor;
+
+ if ((infoPtr->pScrn->bitsPerPixel == 8) &&
+ !(infoPtr->Flags & HARDWARE_CURSOR_TRUECOLOR_AT_8BPP)) {
+ ScreenPriv->InstallColormap = pScreen->InstallColormap;
+ pScreen->InstallColormap = xf86CursorInstallColormap;
+ ScreenPriv->PalettedCursor = TRUE;
+ }
+
+ PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
+
+ ScreenPriv->showTransparent = PointPriv->showTransparent;
+ if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT)
+ PointPriv->showTransparent = TRUE;
+ else
+ PointPriv->showTransparent = FALSE;
+ ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
+ PointPriv->spriteFuncs = &xf86CursorSpriteFuncs;
+
+ ScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess;
+ ScreenPriv->SwitchMode = pScrn->SwitchMode;
+
+ ScreenPriv->ForceHWCursorCount = 0;
+ ScreenPriv->HWCursorForced = FALSE;
+
+ pScrn->EnableDisableFBAccess = xf86CursorEnableDisableFBAccess;
+ if (pScrn->SwitchMode)
+ pScrn->SwitchMode = xf86CursorSwitchMode;
+
+ return TRUE;
+}
+
+/***** Screen functions *****/
+
+static Bool
+xf86CursorCloseScreen(int i, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, miPointerScreenKey);
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (ScreenPriv->isUp && pScrn->vtSema)
+ xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
+
+ if (ScreenPriv->CurrentCursor)
+ FreeCursor(ScreenPriv->CurrentCursor, None);
+
+ pScreen->CloseScreen = ScreenPriv->CloseScreen;
+ pScreen->QueryBestSize = ScreenPriv->QueryBestSize;
+ pScreen->RecolorCursor = ScreenPriv->RecolorCursor;
+ if (ScreenPriv->InstallColormap)
+ pScreen->InstallColormap = ScreenPriv->InstallColormap;
+
+ PointPriv->spriteFuncs = ScreenPriv->spriteFuncs;
+ PointPriv->showTransparent = ScreenPriv->showTransparent;
+
+ pScrn->EnableDisableFBAccess = ScreenPriv->EnableDisableFBAccess;
+ pScrn->SwitchMode = ScreenPriv->SwitchMode;
+
+ free(ScreenPriv->transparentData);
+ free(ScreenPriv);
+
+ return (*pScreen->CloseScreen)(i, pScreen);
+}
+
+static void
+xf86CursorQueryBestSize(
+ int class,
+ unsigned short *width,
+ unsigned short *height,
+ ScreenPtr pScreen)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (class == CursorShape) {
+ if(*width > ScreenPriv->CursorInfoPtr->MaxWidth)
+ *width = ScreenPriv->CursorInfoPtr->MaxWidth;
+ if(*height > ScreenPriv->CursorInfoPtr->MaxHeight)
+ *height = ScreenPriv->CursorInfoPtr->MaxHeight;
+ } else
+ (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
+}
+
+static void
+xf86CursorInstallColormap(ColormapPtr pMap)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pMap->pScreen->devPrivates, xf86CursorScreenKey);
+
+ ScreenPriv->pInstalledMap = pMap;
+
+ (*ScreenPriv->InstallColormap)(pMap);
+}
+
+static void
+xf86CursorRecolorCursor(
+ DeviceIntPtr pDev,
+ ScreenPtr pScreen,
+ CursorPtr pCurs,
+ Bool displayed)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (!displayed)
+ return;
+
+ if (ScreenPriv->SWCursor)
+ (*ScreenPriv->RecolorCursor)(pDev, pScreen, pCurs, displayed);
+ else
+ xf86RecolorCursor(pScreen, pCurs, displayed);
+}
+
+/***** ScrnInfoRec functions *********/
+
+static void
+xf86CursorEnableDisableFBAccess(
+ int index,
+ Bool enable)
+{
+ DeviceIntPtr pDev = inputInfo.pointer;
+
+ ScreenPtr pScreen = screenInfo.screens[index];
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (!enable && ScreenPriv->CurrentCursor != NullCursor) {
+ CursorPtr currentCursor = ScreenPriv->CurrentCursor;
+ xf86CursorSetCursor(pDev, pScreen, NullCursor, ScreenPriv->x,
+ ScreenPriv->y);
+ ScreenPriv->isUp = FALSE;
+ ScreenPriv->SWCursor = TRUE;
+ ScreenPriv->SavedCursor = currentCursor;
+ }
+
+ if (ScreenPriv->EnableDisableFBAccess)
+ (*ScreenPriv->EnableDisableFBAccess)(index, enable);
+
+ if (enable && ScreenPriv->SavedCursor)
+ {
+ /*
+ * Re-set current cursor so drivers can react to FB access having been
+ * temporarily disabled.
+ */
+ xf86CursorSetCursor(pDev, pScreen, ScreenPriv->SavedCursor,
+ ScreenPriv->x, ScreenPriv->y);
+ ScreenPriv->SavedCursor = NULL;
+ }
+}
+
+static Bool
+xf86CursorSwitchMode(int index, DisplayModePtr mode, int flags)
+{
+ Bool ret;
+ ScreenPtr pScreen = screenInfo.screens[index];
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (ScreenPriv->isUp) {
+ xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
+ ScreenPriv->isUp = FALSE;
+ }
+
+ ret = (*ScreenPriv->SwitchMode)(index, mode, flags);
+
+ /*
+ * Cannot restore cursor here because the new frame[XY][01] haven't been
+ * calculated yet. However, because the hardware cursor was removed above,
+ * ensure the cursor is repainted by miPointerWarpCursor().
+ */
+ ScreenPriv->CursorToRestore = ScreenPriv->CurrentCursor;
+ miPointerSetWaitForUpdate(pScreen, FALSE); /* Force cursor repaint */
+
+ return ret;
+}
+
+/****** miPointerSpriteFunctions *******/
+
+static Bool
+xf86CursorRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (pCurs->refcnt <= 1)
+ dixSetPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen), NULL);
+
+ return (*ScreenPriv->spriteFuncs->RealizeCursor)(pDev, pScreen, pCurs);
+}
+
+static Bool
+xf86CursorUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+ CursorPtr pCurs)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (pCurs->refcnt <= 1) {
+ free(dixLookupPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen)));
+ dixSetPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen), NULL);
+ }
+
+ return (*ScreenPriv->spriteFuncs->UnrealizeCursor)(pDev, pScreen, pCurs);
+}
+
+static void
+xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
+ int x, int y)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+ xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
+
+ if (pCurs == NullCursor) { /* means we're supposed to remove the cursor */
+ if (ScreenPriv->SWCursor ||
+ !(GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer))
+ (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y);
+ else if (ScreenPriv->isUp) {
+ xf86SetCursor(pScreen, NullCursor, x, y);
+ ScreenPriv->isUp = FALSE;
+ }
+ if (ScreenPriv->CurrentCursor)
+ FreeCursor(ScreenPriv->CurrentCursor, None);
+ ScreenPriv->CurrentCursor = NullCursor;
+ return;
+ }
+
+ /* only update for VCP, otherwise we get cursor jumps when removing a
+ sprite. The second cursor is never HW rendered anyway. */
+ if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer)
+ {
+ pCurs->refcnt++;
+ if (ScreenPriv->CurrentCursor)
+ FreeCursor(ScreenPriv->CurrentCursor, None);
+ ScreenPriv->CurrentCursor = pCurs;
+ ScreenPriv->x = x;
+ ScreenPriv->y = y;
+ ScreenPriv->CursorToRestore = NULL;
+ ScreenPriv->HotX = pCurs->bits->xhot;
+ ScreenPriv->HotY = pCurs->bits->yhot;
+
+ if (!infoPtr->pScrn->vtSema)
+ ScreenPriv->SavedCursor = pCurs;
+
+ if (infoPtr->pScrn->vtSema && (ScreenPriv->ForceHWCursorCount || ((
+#ifdef ARGB_CURSOR
+ pCurs->bits->argb && infoPtr->UseHWCursorARGB &&
+ (*infoPtr->UseHWCursorARGB) (pScreen, pCurs) ) || (
+ pCurs->bits->argb == 0 &&
+#endif
+ (pCurs->bits->height <= infoPtr->MaxHeight) &&
+ (pCurs->bits->width <= infoPtr->MaxWidth) &&
+ (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor)(pScreen, pCurs))))))
+ {
+
+ if (ScreenPriv->SWCursor) /* remove the SW cursor */
+ (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y);
+
+ xf86SetCursor(pScreen, pCurs, x, y);
+ ScreenPriv->SWCursor = FALSE;
+ ScreenPriv->isUp = TRUE;
+
+ miPointerSetWaitForUpdate(pScreen, !infoPtr->pScrn->silkenMouse);
+ return;
+ }
+
+ miPointerSetWaitForUpdate(pScreen, TRUE);
+
+ if (ScreenPriv->isUp) {
+ /* Remove the HW cursor, or make it transparent */
+ if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT) {
+ xf86SetTransparentCursor(pScreen);
+ } else {
+ xf86SetCursor(pScreen, NullCursor, x, y);
+ ScreenPriv->isUp = FALSE;
+ }
+ }
+
+ if (!ScreenPriv->SWCursor)
+ ScreenPriv->SWCursor = TRUE;
+
+ }
+
+ if (pCurs->bits->emptyMask && !ScreenPriv->showTransparent)
+ pCurs = NullCursor;
+
+ (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, pCurs, x, y);
+}
+
+static void
+xf86CursorMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ /* only update coordinate state for first sprite, otherwise we get jumps
+ when removing a sprite. The second sprite is never HW rendered anyway */
+ if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer)
+ {
+ ScreenPriv->x = x;
+ ScreenPriv->y = y;
+
+ if (ScreenPriv->CursorToRestore)
+ xf86CursorSetCursor(pDev, pScreen, ScreenPriv->CursorToRestore, x, y);
+ else if (ScreenPriv->SWCursor)
+ (*ScreenPriv->spriteFuncs->MoveCursor)(pDev, pScreen, x, y);
+ else if (ScreenPriv->isUp)
+ xf86MoveCursor(pScreen, x, y);
+ } else
+ (*ScreenPriv->spriteFuncs->MoveCursor)(pDev, pScreen, x, y);
+}
+
+void
+xf86ForceHWCursor (ScreenPtr pScreen, Bool on)
+{
+ DeviceIntPtr pDev = inputInfo.pointer;
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (on)
+ {
+ if (ScreenPriv->ForceHWCursorCount++ == 0)
+ {
+ if (ScreenPriv->SWCursor && ScreenPriv->CurrentCursor)
+ {
+ ScreenPriv->HWCursorForced = TRUE;
+ xf86CursorSetCursor (pDev, pScreen, ScreenPriv->CurrentCursor,
+ ScreenPriv->x, ScreenPriv->y);
+ }
+ else
+ ScreenPriv->HWCursorForced = FALSE;
+ }
+ }
+ else
+ {
+ if (--ScreenPriv->ForceHWCursorCount == 0)
+ {
+ if (ScreenPriv->HWCursorForced && ScreenPriv->CurrentCursor)
+ xf86CursorSetCursor (pDev, pScreen, ScreenPriv->CurrentCursor,
+ ScreenPriv->x, ScreenPriv->y);
+ }
+ }
+}
+
+xf86CursorInfoPtr
+xf86CreateCursorInfoRec(void)
+{
+ return calloc(1, sizeof(xf86CursorInfoRec));
+}
+
+void
+xf86DestroyCursorInfoRec(xf86CursorInfoPtr infoPtr)
+{
+ free(infoPtr);
+}
+
+/**
+ * New cursor has been created. Do your initalizations here.
+ */
+static Bool
+xf86DeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ int ret;
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ /* Init SW cursor */
+ ret = (*ScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen);
+
+ return ret;
+}
+
+/**
+ * Cursor has been removed. Clean up after yourself.
+ */
+static void
+xf86DeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ /* Clean up SW cursor */
+ (*ScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
+}
+
diff --git a/xorg-server/hw/xfree86/vbe/vbe.c b/xorg-server/hw/xfree86/vbe/vbe.c
index 04132d956..082cfae4f 100644
--- a/xorg-server/hw/xfree86/vbe/vbe.c
+++ b/xorg-server/hw/xfree86/vbe/vbe.c
@@ -1,1089 +1,1089 @@
-
-/*
- * XFree86 vbe module
- * Copyright 2000 Egbert Eich
- *
- * The mode query/save/set/restore functions from the vesa driver
- * have been moved here.
- * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
- * Authors: Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "xf86.h"
-#include "vbe.h"
-#include <X11/extensions/dpmsconst.h>
-
-#define VERSION(x) VBE_VERSION_MAJOR(x),VBE_VERSION_MINOR(x)
-
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
-#define B_O16(x) (x)
-#define B_O32(x) (x)
-#else
-#define B_O16(x) ((((x) & 0xff) << 8) | (((x) & 0xff) >> 8))
-#define B_O32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) \
- | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))
-#endif
-#define L_ADD(x) (B_O32(x) & 0xffff) + ((B_O32(x) >> 12) & 0xffff00)
-
-#define FARP(p) (((unsigned)(p & 0xffff0000) >> 12) | (p & 0xffff))
-#define R16(v) ((v) & 0xffff)
-
-static unsigned char * vbeReadEDID(vbeInfoPtr pVbe);
-static Bool vbeProbeDDC(vbeInfoPtr pVbe);
-
-static const char vbeVersionString[] = "VBE2";
-
-vbeInfoPtr
-VBEInit(xf86Int10InfoPtr pInt, int entityIndex)
-{
- return VBEExtendedInit(pInt, entityIndex, 0);
-}
-
-vbeInfoPtr
-VBEExtendedInit(xf86Int10InfoPtr pInt, int entityIndex, int Flags)
-{
- int RealOff;
- pointer page = NULL;
- ScrnInfoPtr pScrn = xf86FindScreenForEntity(entityIndex);
- vbeControllerInfoPtr vbe = NULL;
- Bool init_int10 = FALSE;
- vbeInfoPtr vip = NULL;
- int screen;
-
- if (!pScrn) return NULL;
- screen = pScrn->scrnIndex;
-
- if (!pInt) {
- if (!xf86LoadSubModule(pScrn, "int10"))
- goto error;
-
- xf86DrvMsg(screen,X_INFO,"initializing int10\n");
- pInt = xf86ExtendedInitInt10(entityIndex,Flags);
- if (!pInt)
- goto error;
- init_int10 = TRUE;
- }
-
- page = xf86Int10AllocPages(pInt,1,&RealOff);
- if (!page) goto error;
- vbe = (vbeControllerInfoPtr) page;
- memcpy(vbe->VbeSignature,vbeVersionString,4);
-
- pInt->ax = 0x4F00;
- pInt->es = SEG_ADDR(RealOff);
- pInt->di = SEG_OFF(RealOff);
- pInt->num = 0x10;
-
- xf86ExecX86int10(pInt);
-
- if ((pInt->ax & 0xff) != 0x4f) {
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA BIOS not detected\n");
- goto error;
- }
-
- switch (pInt->ax & 0xff00) {
- case 0:
- xf86DrvMsg(screen,X_INFO,"VESA BIOS detected\n");
- break;
- case 0x100:
- xf86DrvMsg(screen,X_INFO,"VESA BIOS function failed\n");
- goto error;
- case 0x200:
- xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported\n");
- goto error;
- case 0x300:
- xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported in current mode\n");
- goto error;
- default:
- xf86DrvMsg(screen,X_INFO,"Invalid\n");
- goto error;
- }
-
- xf86DrvMsgVerb(screen, X_INFO, 4,
- "VbeVersion is %d, OemStringPtr is 0x%08lx,\n"
- "\tOemVendorNamePtr is 0x%08lx, OemProductNamePtr is 0x%08lx,\n"
- "\tOemProductRevPtr is 0x%08lx\n",
- vbe->VbeVersion, (unsigned long)vbe->OemStringPtr,
- (unsigned long)vbe->OemVendorNamePtr,
- (unsigned long)vbe->OemProductNamePtr,
- (unsigned long)vbe->OemProductRevPtr);
-
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Version %i.%i\n",
- VERSION(vbe->VbeVersion));
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Total Mem: %i kB\n",
- vbe->TotalMem * 64);
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM: %s\n",
- (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemStringPtr)));
-
- if (B_O16(vbe->VbeVersion) >= 0x200) {
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Software Rev: %i.%i\n",
- VERSION(vbe->OemSoftwareRev));
- if (vbe->OemVendorNamePtr)
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Vendor: %s\n",
- (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemVendorNamePtr)));
- if (vbe->OemProductNamePtr)
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product: %s\n",
- (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductNamePtr)));
- if (vbe->OemProductRevPtr)
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product Rev: %s\n",
- (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductRevPtr)));
- }
- vip = (vbeInfoPtr)xnfalloc(sizeof(vbeInfoRec));
- vip->version = B_O16(vbe->VbeVersion);
- vip->pInt10 = pInt;
- vip->ddc = DDC_UNCHECKED;
- vip->memory = page;
- vip->real_mode_base = RealOff;
- vip->num_pages = 1;
- vip->init_int10 = init_int10;
-
- return vip;
-
- error:
- if (page)
- xf86Int10FreePages(pInt, page, 1);
- if (init_int10)
- xf86FreeInt10(pInt);
- return NULL;
-}
-
-void
-vbeFree(vbeInfoPtr pVbe)
-{
- if (!pVbe)
- return;
-
- xf86Int10FreePages(pVbe->pInt10,pVbe->memory,pVbe->num_pages);
- /* If we have initalized int10 we ought to free it, too */
- if (pVbe->init_int10)
- xf86FreeInt10(pVbe->pInt10);
- free(pVbe);
- return;
-}
-
-static Bool
-vbeProbeDDC(vbeInfoPtr pVbe)
-{
- char *ddc_level;
- int screen = pVbe->pInt10->scrnIndex;
-
- if (pVbe->ddc == DDC_NONE)
- return FALSE;
- if (pVbe->ddc != DDC_UNCHECKED)
- return TRUE;
-
- pVbe->pInt10->ax = 0x4F15;
- pVbe->pInt10->bx = 0;
- pVbe->pInt10->cx = 0;
- pVbe->pInt10->es = 0;
- pVbe->pInt10->di = 0;
- pVbe->pInt10->num = 0x10;
-
- xf86ExecX86int10(pVbe->pInt10);
-
- if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC not supported\n");
- pVbe->ddc = DDC_NONE;
- return FALSE;
- }
-
- switch ((pVbe->pInt10->ax >> 8) & 0xff) {
- case 0:
- xf86DrvMsg(screen,X_INFO,"VESA VBE DDC supported\n");
- switch (pVbe->pInt10->bx & 0x3) {
- case 0:
- ddc_level = " none";
- pVbe->ddc = DDC_NONE;
- break;
- case 1:
- ddc_level = " 1";
- pVbe->ddc = DDC_1;
- break;
- case 2:
- ddc_level = " 2";
- pVbe->ddc = DDC_2;
- break;
- case 3:
- ddc_level = " 1 + 2";
- pVbe->ddc = DDC_1_2;
- break;
- default:
- ddc_level = "";
- pVbe->ddc = DDC_NONE;
- break;
- }
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Level%s\n",ddc_level);
- if (pVbe->pInt10->bx & 0x4) {
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Screen blanked"
- "for data transfer\n");
- pVbe->ddc_blank = TRUE;
- } else
- pVbe->ddc_blank = FALSE;
-
- xf86DrvMsgVerb(screen,X_INFO,3,
- "VESA VBE DDC transfer in appr. %x sec.\n",
- (pVbe->pInt10->bx >> 8) & 0xff);
- }
-
- return TRUE;
-}
-
-typedef enum {
- VBEOPT_NOVBE,
- VBEOPT_NODDC
-} VBEOpts;
-
-static const OptionInfoRec VBEOptions[] = {
- { VBEOPT_NOVBE, "NoVBE", OPTV_BOOLEAN, {0}, FALSE },
- { VBEOPT_NODDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL, OPTV_NONE, {0}, FALSE },
-};
-
-static unsigned char *
-vbeReadEDID(vbeInfoPtr pVbe)
-{
- int RealOff = pVbe->real_mode_base;
- pointer page = pVbe->memory;
- unsigned char *tmp = NULL;
- Bool novbe = FALSE;
- Bool noddc = FALSE;
- int screen = pVbe->pInt10->scrnIndex;
- OptionInfoPtr options;
-
- if (!page) return NULL;
-
- options = xnfalloc(sizeof(VBEOptions));
- (void)memcpy(options, VBEOptions, sizeof(VBEOptions));
- xf86ProcessOptions(screen, xf86Screens[screen]->options, options);
- xf86GetOptValBool(options, VBEOPT_NOVBE, &novbe);
- xf86GetOptValBool(options, VBEOPT_NODDC, &noddc);
- free(options);
- if (novbe || noddc) return NULL;
-
- if (!vbeProbeDDC(pVbe)) goto error;
-
- memset(page,0,sizeof(vbeInfoPtr));
- strcpy(page,vbeVersionString);
-
- pVbe->pInt10->ax = 0x4F15;
- pVbe->pInt10->bx = 0x01;
- pVbe->pInt10->cx = 0;
- pVbe->pInt10->dx = 0;
- pVbe->pInt10->es = SEG_ADDR(RealOff);
- pVbe->pInt10->di = SEG_OFF(RealOff);
- pVbe->pInt10->num = 0x10;
-
- xf86ExecX86int10(pVbe->pInt10);
-
- if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC invalid\n");
- goto error;
- }
- switch (pVbe->pInt10->ax & 0xff00) {
- case 0x0:
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read successfully\n");
- tmp = (unsigned char *)xnfalloc(128);
- memcpy(tmp,page,128);
- break;
- case 0x100:
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read failed\n");
- break;
- default:
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC unkown failure %i\n",
- pVbe->pInt10->ax & 0xff00);
- break;
- }
-
- error:
- return tmp;
-}
-
-xf86MonPtr
-vbeDoEDID(vbeInfoPtr pVbe, pointer pDDCModule)
-{
- xf86MonPtr pMonitor;
- pointer pModule;
- unsigned char *DDC_data = NULL;
-
- if (!pVbe) return NULL;
- if (pVbe->version < 0x200)
- return NULL;
-
- if (!(pModule = pDDCModule)) {
- pModule =
- xf86LoadSubModule(xf86Screens[pVbe->pInt10->scrnIndex], "ddc");
- if (!pModule)
- return NULL;
- }
-
- DDC_data = vbeReadEDID(pVbe);
-
- if (!DDC_data)
- return NULL;
-
- pMonitor = xf86InterpretEDID(pVbe->pInt10->scrnIndex, DDC_data);
-
- if (!pDDCModule)
- xf86UnloadSubModule(pModule);
- return pMonitor;
-}
-
-#define GET_UNALIGNED2(x) \
- ((*(CARD16*)(x)) | (*(((CARD16*)(x) + 1))) << 16)
-
-VbeInfoBlock *
-VBEGetVBEInfo(vbeInfoPtr pVbe)
-{
- VbeInfoBlock *block = NULL;
- int i, pStr, pModes;
- char *str;
- CARD16 major, *modes;
-
- memset(pVbe->memory, 0, sizeof(VbeInfoBlock));
-
- /*
- Input:
- AH := 4Fh Super VGA support
- AL := 00h Return Super VGA information
- ES:DI := Pointer to buffer
-
- Output:
- AX := status
- (All other registers are preserved)
- */
-
- ((char*)pVbe->memory)[0] = 'V';
- ((char*)pVbe->memory)[1] = 'B';
- ((char*)pVbe->memory)[2] = 'E';
- ((char*)pVbe->memory)[3] = '2';
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f00;
- pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
- pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return NULL;
-
- block = calloc(sizeof(VbeInfoBlock), 1);
- block->VESASignature[0] = ((char*)pVbe->memory)[0];
- block->VESASignature[1] = ((char*)pVbe->memory)[1];
- block->VESASignature[2] = ((char*)pVbe->memory)[2];
- block->VESASignature[3] = ((char*)pVbe->memory)[3];
-
- block->VESAVersion = *(CARD16*)(((char*)pVbe->memory) + 4);
- major = (unsigned)block->VESAVersion >> 8;
-
- pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 6));
- str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
- block->OEMStringPtr = strdup(str);
-
- block->Capabilities[0] = ((char*)pVbe->memory)[10];
- block->Capabilities[1] = ((char*)pVbe->memory)[11];
- block->Capabilities[2] = ((char*)pVbe->memory)[12];
- block->Capabilities[3] = ((char*)pVbe->memory)[13];
-
- pModes = GET_UNALIGNED2((((char*)pVbe->memory) + 14));
- modes = xf86int10Addr(pVbe->pInt10, FARP(pModes));
- i = 0;
- while (modes[i] != 0xffff)
- i++;
- block->VideoModePtr = malloc(sizeof(CARD16) * (i + 1));
- memcpy(block->VideoModePtr, modes, sizeof(CARD16) * i);
- block->VideoModePtr[i] = 0xffff;
-
- block->TotalMemory = *(CARD16*)(((char*)pVbe->memory) + 18);
-
- if (major < 2)
- memcpy(&block->OemSoftwareRev, ((char*)pVbe->memory) + 20, 236);
- else {
- block->OemSoftwareRev = *(CARD16*)(((char*)pVbe->memory) + 20);
- pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 22));
- str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
- block->OemVendorNamePtr = strdup(str);
- pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 26));
- str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
- block->OemProductNamePtr = strdup(str);
- pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 30));
- str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
- block->OemProductRevPtr = strdup(str);
- memcpy(&block->Reserved, ((char*)pVbe->memory) + 34, 222);
- memcpy(&block->OemData, ((char*)pVbe->memory) + 256, 256);
- }
-
- return block;
-}
-
-void
-VBEFreeVBEInfo(VbeInfoBlock *block)
-{
- free(block->OEMStringPtr);
- free(block->VideoModePtr);
- if (((unsigned)block->VESAVersion >> 8) >= 2) {
- free(block->OemVendorNamePtr);
- free(block->OemProductNamePtr);
- free(block->OemProductRevPtr);
- }
- free(block);
-}
-
-Bool
-VBESetVBEMode(vbeInfoPtr pVbe, int mode, VbeCRTCInfoBlock *block)
-{
- /*
- Input:
- AH := 4Fh Super VGA support
- AL := 02h Set Super VGA video mode
- BX := Video mode
- D0-D8 := Mode number
- D9-D10 := Reserved (must be 0)
- D11 := 0 Use current default refresh rate
- := 1 Use user specified CRTC values for refresh rate
- D12-13 Reserved for VBE/AF (must be 0)
- D14 := 0 Use windowed frame buffer model
- := 1 Use linear/flat frame buffer model
- D15 := 0 Clear video memory
- := 1 Don't clear video memory
- ES:DI := Pointer to VbeCRTCInfoBlock structure
-
- Output: AX = Status
- (All other registers are preserved)
- */
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f02;
- pVbe->pInt10->bx = mode;
- if (block) {
- pVbe->pInt10->bx |= 1 << 11;
- memcpy(pVbe->memory, block, sizeof(VbeCRTCInfoBlock));
- pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
- pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
- } else
- pVbe->pInt10->bx &= ~(1 << 11);
-
- xf86ExecX86int10(pVbe->pInt10);
-
- return (R16(pVbe->pInt10->ax) == 0x4f);
-}
-
-Bool
-VBEGetVBEMode(vbeInfoPtr pVbe, int *mode)
-{
- /*
- Input:
- AH := 4Fh Super VGA support
- AL := 03h Return current video mode
-
- Output:
- AX := Status
- BX := Current video mode
- (All other registers are preserved)
- */
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f03;
-
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) == 0x4f) {
- *mode = R16(pVbe->pInt10->bx);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-VbeModeInfoBlock *
-VBEGetModeInfo(vbeInfoPtr pVbe, int mode)
-{
- VbeModeInfoBlock *block = NULL;
-
- memset(pVbe->memory, 0, sizeof(VbeModeInfoBlock));
-
- /*
- Input:
- AH := 4Fh Super VGA support
- AL := 01h Return Super VGA mode information
- CX := Super VGA video mode
- (mode number must be one of those returned by Function 0)
- ES:DI := Pointer to buffer
-
- Output:
- AX := status
- (All other registers are preserved)
- */
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f01;
- pVbe->pInt10->cx = mode;
- pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
- pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
- xf86ExecX86int10(pVbe->pInt10);
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return NULL;
-
- block = malloc(sizeof(VbeModeInfoBlock));
- if (block)
- memcpy(block, pVbe->memory, sizeof(*block));
-
- return block;
-}
-
-void
-VBEFreeModeInfo(VbeModeInfoBlock *block)
-{
- free(block);
-}
-
-Bool
-VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction function,
- pointer *memory, int *size, int *real_mode_pages)
-{
- /*
- Input:
- AH := 4Fh Super VGA support
- AL := 04h Save/restore Super VGA video state
- DL := 00h Return save/restore state buffer size
- CX := Requested states
- D0 = Save/restore video hardware state
- D1 = Save/restore video BIOS data state
- D2 = Save/restore video DAC state
- D3 = Save/restore Super VGA state
-
- Output:
- AX = Status
- BX = Number of 64-byte blocks to hold the state buffer
- (All other registers are preserved)
-
-
- Input:
- AH := 4Fh Super VGA support
- AL := 04h Save/restore Super VGA video state
- DL := 01h Save Super VGA video state
- CX := Requested states (see above)
- ES:BX := Pointer to buffer
-
- Output:
- AX := Status
- (All other registers are preserved)
-
-
- Input:
- AH := 4Fh Super VGA support
- AL := 04h Save/restore Super VGA video state
- DL := 02h Restore Super VGA video state
- CX := Requested states (see above)
- ES:BX := Pointer to buffer
-
- Output:
- AX := Status
- (All other registers are preserved)
- */
-
- if ((pVbe->version & 0xff00) > 0x100) {
- int screen = pVbe->pInt10->scrnIndex;
- if (function == MODE_QUERY ||
- (function == MODE_SAVE && !*memory)) {
- /* Query amount of memory to save state */
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f04;
- pVbe->pInt10->dx = 0;
- pVbe->pInt10->cx = 0x000f;
- xf86ExecX86int10(pVbe->pInt10);
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return FALSE;
-
- if (function == MODE_SAVE) {
- int npages = (R16(pVbe->pInt10->bx) * 64) / 4096 + 1;
- if ((*memory = xf86Int10AllocPages(pVbe->pInt10, npages,
- real_mode_pages)) == NULL) {
- xf86DrvMsg(screen, X_ERROR,
- "Cannot allocate memory to save SVGA state.\n");
- return FALSE;
- }
- }
- *size = pVbe->pInt10->bx * 64;
- }
-
- /* Save/Restore Super VGA state */
- if (function != MODE_QUERY) {
-
- if (!*memory) return FALSE;
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f04;
- switch (function) {
- case MODE_SAVE:
- pVbe->pInt10->dx = 1;
- break;
- case MODE_RESTORE:
- pVbe->pInt10->dx = 2;
- break;
- case MODE_QUERY:
- return FALSE;
- }
- pVbe->pInt10->cx = 0x000f;
-
- pVbe->pInt10->es = SEG_ADDR(*real_mode_pages);
- pVbe->pInt10->bx = SEG_OFF(*real_mode_pages);
- xf86ExecX86int10(pVbe->pInt10);
- return (R16(pVbe->pInt10->ax) == 0x4f);
-
- }
- }
- return TRUE;
-}
-
-Bool
-VBEBankSwitch(vbeInfoPtr pVbe, unsigned int iBank, int window)
-{
- /*
- Input:
- AH := 4Fh Super VGA support
- AL := 05h
-
- Output:
- */
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f05;
- pVbe->pInt10->bx = window;
- pVbe->pInt10->dx = iBank;
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return FALSE;
-
- return TRUE;
-}
-
-Bool
-VBESetGetLogicalScanlineLength(vbeInfoPtr pVbe, vbeScanwidthCommand command,
- int width, int *pixels, int *bytes, int *max)
-{
- if (command < SCANWID_SET || command > SCANWID_GET_MAX)
- return FALSE;
-
- /*
- Input:
- AX := 4F06h VBE Set/Get Logical Scan Line Length
- BL := 00h Set Scan Line Length in Pixels
- := 01h Get Scan Line Length
- := 02h Set Scan Line Length in Bytes
- := 03h Get Maximum Scan Line Length
- CX := If BL=00h Desired Width in Pixels
- If BL=02h Desired Width in Bytes
- (Ignored for Get Functions)
-
- Output:
- AX := VBE Return Status
- BX := Bytes Per Scan Line
- CX := Actual Pixels Per Scan Line
- (truncated to nearest complete pixel)
- DX := Maximum Number of Scan Lines
- */
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f06;
- pVbe->pInt10->bx = command;
- if (command == SCANWID_SET || command == SCANWID_SET_BYTES)
- pVbe->pInt10->cx = width;
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return FALSE;
-
- if (command == SCANWID_GET || command == SCANWID_GET_MAX) {
- if (pixels)
- *pixels = R16(pVbe->pInt10->cx);
- if (bytes)
- *bytes = R16(pVbe->pInt10->bx);
- if (max)
- *max = R16(pVbe->pInt10->dx);
- }
-
- return TRUE;
-}
-
-Bool
-VBESetDisplayStart(vbeInfoPtr pVbe, int x, int y, Bool wait_retrace)
-{
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f07;
- pVbe->pInt10->bx = wait_retrace ? 0x80 : 0x00;
- pVbe->pInt10->cx = x;
- pVbe->pInt10->dx = y;
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return FALSE;
-
- return TRUE;
-}
-
-Bool
-VBEGetDisplayStart(vbeInfoPtr pVbe, int *x, int *y)
-{
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f07;
- pVbe->pInt10->bx = 0x01;
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return FALSE;
-
- *x = pVbe->pInt10->cx;
- *y = pVbe->pInt10->dx;
-
- return TRUE;
-}
-
-int
-VBESetGetDACPaletteFormat(vbeInfoPtr pVbe, int bits)
-{
- /*
- Input:
- AX := 4F08h VBE Set/Get Palette Format
- BL := 00h Set DAC Palette Format
- := 01h Get DAC Palette Format
- BH := Desired bits of color per primary
- (Set DAC Palette Format only)
-
- Output:
- AX := VBE Return Status
- BH := Current number of bits of color per primary
- */
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f08;
- if (!bits)
- pVbe->pInt10->bx = 0x01;
- else
- pVbe->pInt10->bx = (bits & 0x00ff) << 8;
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return 0;
-
- return (bits != 0 ? bits : (pVbe->pInt10->bx >> 8) & 0x00ff);
-}
-
-CARD32 *
-VBESetGetPaletteData(vbeInfoPtr pVbe, Bool set, int first, int num,
- CARD32 *data, Bool secondary, Bool wait_retrace)
-{
- /*
- Input:
- (16-bit)
- AX := 4F09h VBE Load/Unload Palette Data
- BL := 00h Set Palette Data
- := 01h Get Palette Data
- := 02h Set Secondary Palette Data
- := 03h Get Secondary Palette Data
- := 80h Set Palette Data during Vertical Retrace
- CX := Number of palette registers to update (to a maximum of 256)
- DX := First of the palette registers to update (start)
- ES:DI := Table of palette values (see below for format)
-
- Output:
- AX := VBE Return Status
-
-
- Input:
- (32-bit)
- BL := 00h Set Palette Data
- := 80h Set Palette Data during Vertical Retrace
- CX := Number of palette registers to update (to a maximum of 256)
- DX := First of the palette registers to update (start)
- ES:EDI := Table of palette values (see below for format)
- DS := Selector for memory mapped registers
- */
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f09;
- if (!secondary)
- pVbe->pInt10->bx = set && wait_retrace ? 0x80 : set ? 0 : 1;
- else
- pVbe->pInt10->bx = set ? 2 : 3;
- pVbe->pInt10->cx = num;
- pVbe->pInt10->dx = first;
- pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
- pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
- if (set)
- memcpy(pVbe->memory, data, num * sizeof(CARD32));
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return NULL;
-
- if (set)
- return data;
-
- data = malloc(num * sizeof(CARD32));
- memcpy(data, pVbe->memory, num * sizeof(CARD32));
-
- return data;
-}
-
-VBEpmi *
-VBEGetVBEpmi(vbeInfoPtr pVbe)
-{
- VBEpmi *pmi;
-
- /*
- Input:
- AH := 4Fh Super VGA support
- AL := 0Ah Protected Mode Interface
- BL := 00h Return Protected Mode Table
-
- Output:
- AX := Status
- ES := Real Mode Segment of Table
- DI := Offset of Table
- CX := Lenght of Table including protected mode code in bytes (for copying purposes)
- (All other registers are preserved)
- */
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f0a;
- pVbe->pInt10->bx = 0;
- pVbe->pInt10->di = 0;
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return NULL;
-
- pmi = malloc(sizeof(VBEpmi));
- pmi->seg_tbl = R16(pVbe->pInt10->es);
- pmi->tbl_off = R16(pVbe->pInt10->di);
- pmi->tbl_len = R16(pVbe->pInt10->cx);
-
- return pmi;
-}
-
-#if 0
-vbeModeInfoPtr
-VBEBuildVbeModeList(vbeInfoPtr pVbe, VbeInfoBlock *vbe)
-{
- vbeModeInfoPtr ModeList = NULL;
-
- int i = 0;
- while (vbe->VideoModePtr[i] != 0xffff) {
- vbeModeInfoPtr m;
- VbeModeInfoBlock *mode;
- int id = vbe->VideoModePtr[i++];
- int bpp;
-
- if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
- continue;
-
- bpp = mode->BitsPerPixel;
-
- m = xnfcalloc(sizeof(vbeModeInfoRec),1);
- m->width = mode->XResolution;
- m->height = mode->YResolution;
- m->bpp = bpp;
- m->n = id;
- m->next = ModeList;
-
- xf86DrvMsgVerb(pVbe->pInt10->scrnIndex, X_PROBED, 3,
- "BIOS reported VESA mode 0x%x: x:%i y:%i bpp:%i\n",
- m->n, m->width, m->height, m->bpp);
-
- ModeList = m;
-
- VBEFreeModeInfo(mode);
- }
- return ModeList;
-}
-
-unsigned short
-VBECalcVbeModeIndex(vbeModeInfoPtr m, DisplayModePtr mode, int bpp)
-{
- while (m) {
- if (bpp == m->bpp
- && mode->HDisplay == m->width
- && mode->VDisplay == m->height)
- return m->n;
- m = m->next;
- }
- return 0;
-}
-#endif
-
-void
-VBEVesaSaveRestore(vbeInfoPtr pVbe, vbeSaveRestorePtr vbe_sr,
- vbeSaveRestoreFunction function)
-{
- Bool SaveSucc = FALSE;
-
- if (VBE_VERSION_MAJOR(pVbe->version) > 1
- && (function == MODE_SAVE || vbe_sr->pstate)) {
- if (function == MODE_RESTORE)
- memcpy(vbe_sr->state, vbe_sr->pstate, vbe_sr->stateSize);
- ErrorF("VBESaveRestore\n");
- if ((VBESaveRestore(pVbe,function,
- (pointer)&vbe_sr->state,
- &vbe_sr->stateSize,&vbe_sr->statePage))) {
- if (function == MODE_SAVE) {
- SaveSucc = TRUE;
- vbe_sr->stateMode = -1; /* invalidate */
- /* don't rely on the memory not being touched */
- if (vbe_sr->pstate == NULL)
- vbe_sr->pstate = malloc(vbe_sr->stateSize);
- memcpy(vbe_sr->pstate, vbe_sr->state, vbe_sr->stateSize);
- }
- ErrorF("VBESaveRestore done with success\n");
- return;
- }
- ErrorF("VBESaveRestore done\n");
- }
-
- if (function == MODE_SAVE && !SaveSucc)
- (void)VBEGetVBEMode(pVbe, &vbe_sr->stateMode);
-
- if (function == MODE_RESTORE && vbe_sr->stateMode != -1)
- VBESetVBEMode(pVbe, vbe_sr->stateMode, NULL);
-
-}
-
-int
-VBEGetPixelClock(vbeInfoPtr pVbe, int mode, int clock)
-{
- /*
- Input:
- AX := 4F0Bh VBE Get Pixel Clock
- BL := 00h Get Pixel Clock
- ECX := pixel clock in units of Hz
- DX := mode number
-
- Output:
- AX := VBE Return Status
- ECX := Closest pixel clock
- */
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f0b;
- pVbe->pInt10->bx = 0x00;
- pVbe->pInt10->cx = clock;
- pVbe->pInt10->dx = mode;
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return 0;
-
- return pVbe->pInt10->cx;
-}
-
-Bool
-VBEDPMSSet(vbeInfoPtr pVbe, int mode)
-{
- /*
- Input:
- AX := 4F10h DPMS
- BL := 01h Set Display Power State
- BH := requested power state
-
- Output:
- AX := VBE Return Status
- */
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f10;
- pVbe->pInt10->bx = 0x01;
- switch (mode) {
- case DPMSModeOn:
- break;
- case DPMSModeStandby:
- pVbe->pInt10->bx |= 0x100;
- break;
- case DPMSModeSuspend:
- pVbe->pInt10->bx |= 0x200;
- break;
- case DPMSModeOff:
- pVbe->pInt10->bx |= 0x400;
- break;
- }
- xf86ExecX86int10(pVbe->pInt10);
- return (R16(pVbe->pInt10->ax) == 0x4f);
-}
-
-void
-VBEInterpretPanelID(int scrnIndex, struct vbePanelID *data)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- DisplayModePtr mode;
- const float PANEL_HZ = 60.0;
-
- if (!data)
- return;
-
- xf86DrvMsg(scrnIndex, X_INFO, "PanelID returned panel resolution %dx%d\n",
- data->hsize, data->vsize);
-
- if (pScrn->monitor->nHsync || pScrn->monitor->nVrefresh)
- return;
-
- if (data->hsize < 320 || data->vsize < 240) {
- xf86DrvMsg(scrnIndex, X_INFO, "...which I refuse to believe\n");
- return;
- }
-
- mode = xf86CVTMode(data->hsize, data->vsize, PANEL_HZ, 1, 0);
-
- pScrn->monitor->nHsync = 1;
- pScrn->monitor->hsync[0].lo = 31.5;
- pScrn->monitor->hsync[0].hi = (float)mode->Clock / (float)mode->HTotal;
- pScrn->monitor->nVrefresh = 1;
- pScrn->monitor->vrefresh[0].lo = 56.0;
- pScrn->monitor->vrefresh[0].hi =
- (float)mode->Clock*1000.0 / (float)mode->HTotal / (float)mode->VTotal;
-
- free(mode);
-}
-
-struct vbePanelID *
-VBEReadPanelID(vbeInfoPtr pVbe)
-{
- int RealOff = pVbe->real_mode_base;
- pointer page = pVbe->memory;
- void *tmp = NULL;
- int screen = pVbe->pInt10->scrnIndex;
-
- pVbe->pInt10->ax = 0x4F11;
- pVbe->pInt10->bx = 0x01;
- pVbe->pInt10->cx = 0;
- pVbe->pInt10->dx = 0;
- pVbe->pInt10->es = SEG_ADDR(RealOff);
- pVbe->pInt10->di = SEG_OFF(RealOff);
- pVbe->pInt10->num = 0x10;
-
- xf86ExecX86int10(pVbe->pInt10);
-
- if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID invalid\n");
- goto error;
- }
-
- switch (pVbe->pInt10->ax & 0xff00) {
- case 0x0:
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read successfully\n");
- tmp = xnfalloc(32);
- memcpy(tmp, page, 32);
- break;
- case 0x100:
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read failed\n");
- break;
- default:
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID unknown failure %i\n",
- pVbe->pInt10->ax & 0xff00);
- break;
- }
-
-error:
- return tmp;
-}
+
+/*
+ * XFree86 vbe module
+ * Copyright 2000 Egbert Eich
+ *
+ * The mode query/save/set/restore functions from the vesa driver
+ * have been moved here.
+ * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
+ * Authors: Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "xf86.h"
+#include "vbe.h"
+#include <X11/extensions/dpmsconst.h>
+
+#define VERSION(x) VBE_VERSION_MAJOR(x),VBE_VERSION_MINOR(x)
+
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+#define B_O16(x) (x)
+#define B_O32(x) (x)
+#else
+#define B_O16(x) ((((x) & 0xff) << 8) | (((x) & 0xff) >> 8))
+#define B_O32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) \
+ | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))
+#endif
+#define L_ADD(x) (B_O32(x) & 0xffff) + ((B_O32(x) >> 12) & 0xffff00)
+
+#define FARP(p) (((unsigned)(p & 0xffff0000) >> 12) | (p & 0xffff))
+#define R16(v) ((v) & 0xffff)
+
+static unsigned char * vbeReadEDID(vbeInfoPtr pVbe);
+static Bool vbeProbeDDC(vbeInfoPtr pVbe);
+
+static const char vbeVersionString[] = "VBE2";
+
+vbeInfoPtr
+VBEInit(xf86Int10InfoPtr pInt, int entityIndex)
+{
+ return VBEExtendedInit(pInt, entityIndex, 0);
+}
+
+vbeInfoPtr
+VBEExtendedInit(xf86Int10InfoPtr pInt, int entityIndex, int Flags)
+{
+ int RealOff;
+ pointer page = NULL;
+ ScrnInfoPtr pScrn = xf86FindScreenForEntity(entityIndex);
+ vbeControllerInfoPtr vbe = NULL;
+ Bool init_int10 = FALSE;
+ vbeInfoPtr vip = NULL;
+ int screen;
+
+ if (!pScrn) return NULL;
+ screen = pScrn->scrnIndex;
+
+ if (!pInt) {
+ if (!xf86LoadSubModule(pScrn, "int10"))
+ goto error;
+
+ xf86DrvMsg(screen,X_INFO,"initializing int10\n");
+ pInt = xf86ExtendedInitInt10(entityIndex,Flags);
+ if (!pInt)
+ goto error;
+ init_int10 = TRUE;
+ }
+
+ page = xf86Int10AllocPages(pInt,1,&RealOff);
+ if (!page) goto error;
+ vbe = (vbeControllerInfoPtr) page;
+ memcpy(vbe->VbeSignature,vbeVersionString,4);
+
+ pInt->ax = 0x4F00;
+ pInt->es = SEG_ADDR(RealOff);
+ pInt->di = SEG_OFF(RealOff);
+ pInt->num = 0x10;
+
+ xf86ExecX86int10(pInt);
+
+ if ((pInt->ax & 0xff) != 0x4f) {
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA BIOS not detected\n");
+ goto error;
+ }
+
+ switch (pInt->ax & 0xff00) {
+ case 0:
+ xf86DrvMsg(screen,X_INFO,"VESA BIOS detected\n");
+ break;
+ case 0x100:
+ xf86DrvMsg(screen,X_INFO,"VESA BIOS function failed\n");
+ goto error;
+ case 0x200:
+ xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported\n");
+ goto error;
+ case 0x300:
+ xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported in current mode\n");
+ goto error;
+ default:
+ xf86DrvMsg(screen,X_INFO,"Invalid\n");
+ goto error;
+ }
+
+ xf86DrvMsgVerb(screen, X_INFO, 4,
+ "VbeVersion is %d, OemStringPtr is 0x%08lx,\n"
+ "\tOemVendorNamePtr is 0x%08lx, OemProductNamePtr is 0x%08lx,\n"
+ "\tOemProductRevPtr is 0x%08lx\n",
+ vbe->VbeVersion, (unsigned long)vbe->OemStringPtr,
+ (unsigned long)vbe->OemVendorNamePtr,
+ (unsigned long)vbe->OemProductNamePtr,
+ (unsigned long)vbe->OemProductRevPtr);
+
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Version %i.%i\n",
+ VERSION(vbe->VbeVersion));
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Total Mem: %i kB\n",
+ vbe->TotalMem * 64);
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM: %s\n",
+ (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemStringPtr)));
+
+ if (B_O16(vbe->VbeVersion) >= 0x200) {
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Software Rev: %i.%i\n",
+ VERSION(vbe->OemSoftwareRev));
+ if (vbe->OemVendorNamePtr)
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Vendor: %s\n",
+ (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemVendorNamePtr)));
+ if (vbe->OemProductNamePtr)
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product: %s\n",
+ (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductNamePtr)));
+ if (vbe->OemProductRevPtr)
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product Rev: %s\n",
+ (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductRevPtr)));
+ }
+ vip = (vbeInfoPtr)xnfalloc(sizeof(vbeInfoRec));
+ vip->version = B_O16(vbe->VbeVersion);
+ vip->pInt10 = pInt;
+ vip->ddc = DDC_UNCHECKED;
+ vip->memory = page;
+ vip->real_mode_base = RealOff;
+ vip->num_pages = 1;
+ vip->init_int10 = init_int10;
+
+ return vip;
+
+ error:
+ if (page)
+ xf86Int10FreePages(pInt, page, 1);
+ if (init_int10)
+ xf86FreeInt10(pInt);
+ return NULL;
+}
+
+void
+vbeFree(vbeInfoPtr pVbe)
+{
+ if (!pVbe)
+ return;
+
+ xf86Int10FreePages(pVbe->pInt10,pVbe->memory,pVbe->num_pages);
+ /* If we have initalized int10 we ought to free it, too */
+ if (pVbe->init_int10)
+ xf86FreeInt10(pVbe->pInt10);
+ free(pVbe);
+ return;
+}
+
+static Bool
+vbeProbeDDC(vbeInfoPtr pVbe)
+{
+ char *ddc_level;
+ int screen = pVbe->pInt10->scrnIndex;
+
+ if (pVbe->ddc == DDC_NONE)
+ return FALSE;
+ if (pVbe->ddc != DDC_UNCHECKED)
+ return TRUE;
+
+ pVbe->pInt10->ax = 0x4F15;
+ pVbe->pInt10->bx = 0;
+ pVbe->pInt10->cx = 0;
+ pVbe->pInt10->es = 0;
+ pVbe->pInt10->di = 0;
+ pVbe->pInt10->num = 0x10;
+
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC not supported\n");
+ pVbe->ddc = DDC_NONE;
+ return FALSE;
+ }
+
+ switch ((pVbe->pInt10->ax >> 8) & 0xff) {
+ case 0:
+ xf86DrvMsg(screen,X_INFO,"VESA VBE DDC supported\n");
+ switch (pVbe->pInt10->bx & 0x3) {
+ case 0:
+ ddc_level = " none";
+ pVbe->ddc = DDC_NONE;
+ break;
+ case 1:
+ ddc_level = " 1";
+ pVbe->ddc = DDC_1;
+ break;
+ case 2:
+ ddc_level = " 2";
+ pVbe->ddc = DDC_2;
+ break;
+ case 3:
+ ddc_level = " 1 + 2";
+ pVbe->ddc = DDC_1_2;
+ break;
+ default:
+ ddc_level = "";
+ pVbe->ddc = DDC_NONE;
+ break;
+ }
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Level%s\n",ddc_level);
+ if (pVbe->pInt10->bx & 0x4) {
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Screen blanked"
+ "for data transfer\n");
+ pVbe->ddc_blank = TRUE;
+ } else
+ pVbe->ddc_blank = FALSE;
+
+ xf86DrvMsgVerb(screen,X_INFO,3,
+ "VESA VBE DDC transfer in appr. %x sec.\n",
+ (pVbe->pInt10->bx >> 8) & 0xff);
+ }
+
+ return TRUE;
+}
+
+typedef enum {
+ VBEOPT_NOVBE,
+ VBEOPT_NODDC
+} VBEOpts;
+
+static const OptionInfoRec VBEOptions[] = {
+ { VBEOPT_NOVBE, "NoVBE", OPTV_BOOLEAN, {0}, FALSE },
+ { VBEOPT_NODDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE },
+};
+
+static unsigned char *
+vbeReadEDID(vbeInfoPtr pVbe)
+{
+ int RealOff = pVbe->real_mode_base;
+ pointer page = pVbe->memory;
+ unsigned char *tmp = NULL;
+ Bool novbe = FALSE;
+ Bool noddc = FALSE;
+ int screen = pVbe->pInt10->scrnIndex;
+ OptionInfoPtr options;
+
+ if (!page) return NULL;
+
+ options = xnfalloc(sizeof(VBEOptions));
+ (void)memcpy(options, VBEOptions, sizeof(VBEOptions));
+ xf86ProcessOptions(screen, xf86Screens[screen]->options, options);
+ xf86GetOptValBool(options, VBEOPT_NOVBE, &novbe);
+ xf86GetOptValBool(options, VBEOPT_NODDC, &noddc);
+ free(options);
+ if (novbe || noddc) return NULL;
+
+ if (!vbeProbeDDC(pVbe)) goto error;
+
+ memset(page,0,sizeof(vbeInfoPtr));
+ strcpy(page,vbeVersionString);
+
+ pVbe->pInt10->ax = 0x4F15;
+ pVbe->pInt10->bx = 0x01;
+ pVbe->pInt10->cx = 0;
+ pVbe->pInt10->dx = 0;
+ pVbe->pInt10->es = SEG_ADDR(RealOff);
+ pVbe->pInt10->di = SEG_OFF(RealOff);
+ pVbe->pInt10->num = 0x10;
+
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC invalid\n");
+ goto error;
+ }
+ switch (pVbe->pInt10->ax & 0xff00) {
+ case 0x0:
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read successfully\n");
+ tmp = (unsigned char *)xnfalloc(128);
+ memcpy(tmp,page,128);
+ break;
+ case 0x100:
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read failed\n");
+ break;
+ default:
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC unkown failure %i\n",
+ pVbe->pInt10->ax & 0xff00);
+ break;
+ }
+
+ error:
+ return tmp;
+}
+
+xf86MonPtr
+vbeDoEDID(vbeInfoPtr pVbe, pointer pDDCModule)
+{
+ xf86MonPtr pMonitor;
+ pointer pModule;
+ unsigned char *DDC_data = NULL;
+
+ if (!pVbe) return NULL;
+ if (pVbe->version < 0x200)
+ return NULL;
+
+ if (!(pModule = pDDCModule)) {
+ pModule =
+ xf86LoadSubModule(xf86Screens[pVbe->pInt10->scrnIndex], "ddc");
+ if (!pModule)
+ return NULL;
+ }
+
+ DDC_data = vbeReadEDID(pVbe);
+
+ if (!DDC_data)
+ return NULL;
+
+ pMonitor = xf86InterpretEDID(pVbe->pInt10->scrnIndex, DDC_data);
+
+ if (!pDDCModule)
+ xf86UnloadSubModule(pModule);
+ return pMonitor;
+}
+
+#define GET_UNALIGNED2(x) \
+ ((*(CARD16*)(x)) | (*(((CARD16*)(x) + 1))) << 16)
+
+VbeInfoBlock *
+VBEGetVBEInfo(vbeInfoPtr pVbe)
+{
+ VbeInfoBlock *block = NULL;
+ int i, pStr, pModes;
+ char *str;
+ CARD16 major, *modes;
+
+ memset(pVbe->memory, 0, sizeof(VbeInfoBlock));
+
+ /*
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 00h Return Super VGA information
+ ES:DI := Pointer to buffer
+
+ Output:
+ AX := status
+ (All other registers are preserved)
+ */
+
+ ((char*)pVbe->memory)[0] = 'V';
+ ((char*)pVbe->memory)[1] = 'B';
+ ((char*)pVbe->memory)[2] = 'E';
+ ((char*)pVbe->memory)[3] = '2';
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f00;
+ pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
+ pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return NULL;
+
+ block = calloc(sizeof(VbeInfoBlock), 1);
+ block->VESASignature[0] = ((char*)pVbe->memory)[0];
+ block->VESASignature[1] = ((char*)pVbe->memory)[1];
+ block->VESASignature[2] = ((char*)pVbe->memory)[2];
+ block->VESASignature[3] = ((char*)pVbe->memory)[3];
+
+ block->VESAVersion = *(CARD16*)(((char*)pVbe->memory) + 4);
+ major = (unsigned)block->VESAVersion >> 8;
+
+ pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 6));
+ str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
+ block->OEMStringPtr = strdup(str);
+
+ block->Capabilities[0] = ((char*)pVbe->memory)[10];
+ block->Capabilities[1] = ((char*)pVbe->memory)[11];
+ block->Capabilities[2] = ((char*)pVbe->memory)[12];
+ block->Capabilities[3] = ((char*)pVbe->memory)[13];
+
+ pModes = GET_UNALIGNED2((((char*)pVbe->memory) + 14));
+ modes = xf86int10Addr(pVbe->pInt10, FARP(pModes));
+ i = 0;
+ while (modes[i] != 0xffff)
+ i++;
+ block->VideoModePtr = malloc(sizeof(CARD16) * (i + 1));
+ memcpy(block->VideoModePtr, modes, sizeof(CARD16) * i);
+ block->VideoModePtr[i] = 0xffff;
+
+ block->TotalMemory = *(CARD16*)(((char*)pVbe->memory) + 18);
+
+ if (major < 2)
+ memcpy(&block->OemSoftwareRev, ((char*)pVbe->memory) + 20, 236);
+ else {
+ block->OemSoftwareRev = *(CARD16*)(((char*)pVbe->memory) + 20);
+ pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 22));
+ str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
+ block->OemVendorNamePtr = strdup(str);
+ pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 26));
+ str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
+ block->OemProductNamePtr = strdup(str);
+ pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 30));
+ str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
+ block->OemProductRevPtr = strdup(str);
+ memcpy(&block->Reserved, ((char*)pVbe->memory) + 34, 222);
+ memcpy(&block->OemData, ((char*)pVbe->memory) + 256, 256);
+ }
+
+ return block;
+}
+
+void
+VBEFreeVBEInfo(VbeInfoBlock *block)
+{
+ free(block->OEMStringPtr);
+ free(block->VideoModePtr);
+ if (((unsigned)block->VESAVersion >> 8) >= 2) {
+ free(block->OemVendorNamePtr);
+ free(block->OemProductNamePtr);
+ free(block->OemProductRevPtr);
+ }
+ free(block);
+}
+
+Bool
+VBESetVBEMode(vbeInfoPtr pVbe, int mode, VbeCRTCInfoBlock *block)
+{
+ /*
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 02h Set Super VGA video mode
+ BX := Video mode
+ D0-D8 := Mode number
+ D9-D10 := Reserved (must be 0)
+ D11 := 0 Use current default refresh rate
+ := 1 Use user specified CRTC values for refresh rate
+ D12-13 Reserved for VBE/AF (must be 0)
+ D14 := 0 Use windowed frame buffer model
+ := 1 Use linear/flat frame buffer model
+ D15 := 0 Clear video memory
+ := 1 Don't clear video memory
+ ES:DI := Pointer to VbeCRTCInfoBlock structure
+
+ Output: AX = Status
+ (All other registers are preserved)
+ */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f02;
+ pVbe->pInt10->bx = mode;
+ if (block) {
+ pVbe->pInt10->bx |= 1 << 11;
+ memcpy(pVbe->memory, block, sizeof(VbeCRTCInfoBlock));
+ pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
+ pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
+ } else
+ pVbe->pInt10->bx &= ~(1 << 11);
+
+ xf86ExecX86int10(pVbe->pInt10);
+
+ return (R16(pVbe->pInt10->ax) == 0x4f);
+}
+
+Bool
+VBEGetVBEMode(vbeInfoPtr pVbe, int *mode)
+{
+ /*
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 03h Return current video mode
+
+ Output:
+ AX := Status
+ BX := Current video mode
+ (All other registers are preserved)
+ */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f03;
+
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) == 0x4f) {
+ *mode = R16(pVbe->pInt10->bx);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+VbeModeInfoBlock *
+VBEGetModeInfo(vbeInfoPtr pVbe, int mode)
+{
+ VbeModeInfoBlock *block = NULL;
+
+ memset(pVbe->memory, 0, sizeof(VbeModeInfoBlock));
+
+ /*
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 01h Return Super VGA mode information
+ CX := Super VGA video mode
+ (mode number must be one of those returned by Function 0)
+ ES:DI := Pointer to buffer
+
+ Output:
+ AX := status
+ (All other registers are preserved)
+ */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f01;
+ pVbe->pInt10->cx = mode;
+ pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
+ pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
+ xf86ExecX86int10(pVbe->pInt10);
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return NULL;
+
+ block = malloc(sizeof(VbeModeInfoBlock));
+ if (block)
+ memcpy(block, pVbe->memory, sizeof(*block));
+
+ return block;
+}
+
+void
+VBEFreeModeInfo(VbeModeInfoBlock *block)
+{
+ free(block);
+}
+
+Bool
+VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction function,
+ pointer *memory, int *size, int *real_mode_pages)
+{
+ /*
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 04h Save/restore Super VGA video state
+ DL := 00h Return save/restore state buffer size
+ CX := Requested states
+ D0 = Save/restore video hardware state
+ D1 = Save/restore video BIOS data state
+ D2 = Save/restore video DAC state
+ D3 = Save/restore Super VGA state
+
+ Output:
+ AX = Status
+ BX = Number of 64-byte blocks to hold the state buffer
+ (All other registers are preserved)
+
+
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 04h Save/restore Super VGA video state
+ DL := 01h Save Super VGA video state
+ CX := Requested states (see above)
+ ES:BX := Pointer to buffer
+
+ Output:
+ AX := Status
+ (All other registers are preserved)
+
+
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 04h Save/restore Super VGA video state
+ DL := 02h Restore Super VGA video state
+ CX := Requested states (see above)
+ ES:BX := Pointer to buffer
+
+ Output:
+ AX := Status
+ (All other registers are preserved)
+ */
+
+ if ((pVbe->version & 0xff00) > 0x100) {
+ int screen = pVbe->pInt10->scrnIndex;
+ if (function == MODE_QUERY ||
+ (function == MODE_SAVE && !*memory)) {
+ /* Query amount of memory to save state */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f04;
+ pVbe->pInt10->dx = 0;
+ pVbe->pInt10->cx = 0x000f;
+ xf86ExecX86int10(pVbe->pInt10);
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return FALSE;
+
+ if (function == MODE_SAVE) {
+ int npages = (R16(pVbe->pInt10->bx) * 64) / 4096 + 1;
+ if ((*memory = xf86Int10AllocPages(pVbe->pInt10, npages,
+ real_mode_pages)) == NULL) {
+ xf86DrvMsg(screen, X_ERROR,
+ "Cannot allocate memory to save SVGA state.\n");
+ return FALSE;
+ }
+ }
+ *size = pVbe->pInt10->bx * 64;
+ }
+
+ /* Save/Restore Super VGA state */
+ if (function != MODE_QUERY) {
+
+ if (!*memory) return FALSE;
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f04;
+ switch (function) {
+ case MODE_SAVE:
+ pVbe->pInt10->dx = 1;
+ break;
+ case MODE_RESTORE:
+ pVbe->pInt10->dx = 2;
+ break;
+ case MODE_QUERY:
+ return FALSE;
+ }
+ pVbe->pInt10->cx = 0x000f;
+
+ pVbe->pInt10->es = SEG_ADDR(*real_mode_pages);
+ pVbe->pInt10->bx = SEG_OFF(*real_mode_pages);
+ xf86ExecX86int10(pVbe->pInt10);
+ return (R16(pVbe->pInt10->ax) == 0x4f);
+
+ }
+ }
+ return TRUE;
+}
+
+Bool
+VBEBankSwitch(vbeInfoPtr pVbe, unsigned int iBank, int window)
+{
+ /*
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 05h
+
+ Output:
+ */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f05;
+ pVbe->pInt10->bx = window;
+ pVbe->pInt10->dx = iBank;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return FALSE;
+
+ return TRUE;
+}
+
+Bool
+VBESetGetLogicalScanlineLength(vbeInfoPtr pVbe, vbeScanwidthCommand command,
+ int width, int *pixels, int *bytes, int *max)
+{
+ if (command < SCANWID_SET || command > SCANWID_GET_MAX)
+ return FALSE;
+
+ /*
+ Input:
+ AX := 4F06h VBE Set/Get Logical Scan Line Length
+ BL := 00h Set Scan Line Length in Pixels
+ := 01h Get Scan Line Length
+ := 02h Set Scan Line Length in Bytes
+ := 03h Get Maximum Scan Line Length
+ CX := If BL=00h Desired Width in Pixels
+ If BL=02h Desired Width in Bytes
+ (Ignored for Get Functions)
+
+ Output:
+ AX := VBE Return Status
+ BX := Bytes Per Scan Line
+ CX := Actual Pixels Per Scan Line
+ (truncated to nearest complete pixel)
+ DX := Maximum Number of Scan Lines
+ */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f06;
+ pVbe->pInt10->bx = command;
+ if (command == SCANWID_SET || command == SCANWID_SET_BYTES)
+ pVbe->pInt10->cx = width;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return FALSE;
+
+ if (command == SCANWID_GET || command == SCANWID_GET_MAX) {
+ if (pixels)
+ *pixels = R16(pVbe->pInt10->cx);
+ if (bytes)
+ *bytes = R16(pVbe->pInt10->bx);
+ if (max)
+ *max = R16(pVbe->pInt10->dx);
+ }
+
+ return TRUE;
+}
+
+Bool
+VBESetDisplayStart(vbeInfoPtr pVbe, int x, int y, Bool wait_retrace)
+{
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f07;
+ pVbe->pInt10->bx = wait_retrace ? 0x80 : 0x00;
+ pVbe->pInt10->cx = x;
+ pVbe->pInt10->dx = y;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return FALSE;
+
+ return TRUE;
+}
+
+Bool
+VBEGetDisplayStart(vbeInfoPtr pVbe, int *x, int *y)
+{
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f07;
+ pVbe->pInt10->bx = 0x01;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return FALSE;
+
+ *x = pVbe->pInt10->cx;
+ *y = pVbe->pInt10->dx;
+
+ return TRUE;
+}
+
+int
+VBESetGetDACPaletteFormat(vbeInfoPtr pVbe, int bits)
+{
+ /*
+ Input:
+ AX := 4F08h VBE Set/Get Palette Format
+ BL := 00h Set DAC Palette Format
+ := 01h Get DAC Palette Format
+ BH := Desired bits of color per primary
+ (Set DAC Palette Format only)
+
+ Output:
+ AX := VBE Return Status
+ BH := Current number of bits of color per primary
+ */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f08;
+ if (!bits)
+ pVbe->pInt10->bx = 0x01;
+ else
+ pVbe->pInt10->bx = (bits & 0x00ff) << 8;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return 0;
+
+ return (bits != 0 ? bits : (pVbe->pInt10->bx >> 8) & 0x00ff);
+}
+
+CARD32 *
+VBESetGetPaletteData(vbeInfoPtr pVbe, Bool set, int first, int num,
+ CARD32 *data, Bool secondary, Bool wait_retrace)
+{
+ /*
+ Input:
+ (16-bit)
+ AX := 4F09h VBE Load/Unload Palette Data
+ BL := 00h Set Palette Data
+ := 01h Get Palette Data
+ := 02h Set Secondary Palette Data
+ := 03h Get Secondary Palette Data
+ := 80h Set Palette Data during Vertical Retrace
+ CX := Number of palette registers to update (to a maximum of 256)
+ DX := First of the palette registers to update (start)
+ ES:DI := Table of palette values (see below for format)
+
+ Output:
+ AX := VBE Return Status
+
+
+ Input:
+ (32-bit)
+ BL := 00h Set Palette Data
+ := 80h Set Palette Data during Vertical Retrace
+ CX := Number of palette registers to update (to a maximum of 256)
+ DX := First of the palette registers to update (start)
+ ES:EDI := Table of palette values (see below for format)
+ DS := Selector for memory mapped registers
+ */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f09;
+ if (!secondary)
+ pVbe->pInt10->bx = set && wait_retrace ? 0x80 : set ? 0 : 1;
+ else
+ pVbe->pInt10->bx = set ? 2 : 3;
+ pVbe->pInt10->cx = num;
+ pVbe->pInt10->dx = first;
+ pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
+ pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
+ if (set)
+ memcpy(pVbe->memory, data, num * sizeof(CARD32));
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return NULL;
+
+ if (set)
+ return data;
+
+ data = malloc(num * sizeof(CARD32));
+ memcpy(data, pVbe->memory, num * sizeof(CARD32));
+
+ return data;
+}
+
+VBEpmi *
+VBEGetVBEpmi(vbeInfoPtr pVbe)
+{
+ VBEpmi *pmi;
+
+ /*
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 0Ah Protected Mode Interface
+ BL := 00h Return Protected Mode Table
+
+ Output:
+ AX := Status
+ ES := Real Mode Segment of Table
+ DI := Offset of Table
+ CX := Lenght of Table including protected mode code in bytes (for copying purposes)
+ (All other registers are preserved)
+ */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f0a;
+ pVbe->pInt10->bx = 0;
+ pVbe->pInt10->di = 0;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return NULL;
+
+ pmi = malloc(sizeof(VBEpmi));
+ pmi->seg_tbl = R16(pVbe->pInt10->es);
+ pmi->tbl_off = R16(pVbe->pInt10->di);
+ pmi->tbl_len = R16(pVbe->pInt10->cx);
+
+ return pmi;
+}
+
+#if 0
+vbeModeInfoPtr
+VBEBuildVbeModeList(vbeInfoPtr pVbe, VbeInfoBlock *vbe)
+{
+ vbeModeInfoPtr ModeList = NULL;
+
+ int i = 0;
+ while (vbe->VideoModePtr[i] != 0xffff) {
+ vbeModeInfoPtr m;
+ VbeModeInfoBlock *mode;
+ int id = vbe->VideoModePtr[i++];
+ int bpp;
+
+ if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
+ continue;
+
+ bpp = mode->BitsPerPixel;
+
+ m = xnfcalloc(sizeof(vbeModeInfoRec),1);
+ m->width = mode->XResolution;
+ m->height = mode->YResolution;
+ m->bpp = bpp;
+ m->n = id;
+ m->next = ModeList;
+
+ xf86DrvMsgVerb(pVbe->pInt10->scrnIndex, X_PROBED, 3,
+ "BIOS reported VESA mode 0x%x: x:%i y:%i bpp:%i\n",
+ m->n, m->width, m->height, m->bpp);
+
+ ModeList = m;
+
+ VBEFreeModeInfo(mode);
+ }
+ return ModeList;
+}
+
+unsigned short
+VBECalcVbeModeIndex(vbeModeInfoPtr m, DisplayModePtr mode, int bpp)
+{
+ while (m) {
+ if (bpp == m->bpp
+ && mode->HDisplay == m->width
+ && mode->VDisplay == m->height)
+ return m->n;
+ m = m->next;
+ }
+ return 0;
+}
+#endif
+
+void
+VBEVesaSaveRestore(vbeInfoPtr pVbe, vbeSaveRestorePtr vbe_sr,
+ vbeSaveRestoreFunction function)
+{
+ Bool SaveSucc = FALSE;
+
+ if (VBE_VERSION_MAJOR(pVbe->version) > 1
+ && (function == MODE_SAVE || vbe_sr->pstate)) {
+ if (function == MODE_RESTORE)
+ memcpy(vbe_sr->state, vbe_sr->pstate, vbe_sr->stateSize);
+ ErrorF("VBESaveRestore\n");
+ if ((VBESaveRestore(pVbe,function,
+ (pointer)&vbe_sr->state,
+ &vbe_sr->stateSize,&vbe_sr->statePage))) {
+ if (function == MODE_SAVE) {
+ SaveSucc = TRUE;
+ vbe_sr->stateMode = -1; /* invalidate */
+ /* don't rely on the memory not being touched */
+ if (vbe_sr->pstate == NULL)
+ vbe_sr->pstate = malloc(vbe_sr->stateSize);
+ memcpy(vbe_sr->pstate, vbe_sr->state, vbe_sr->stateSize);
+ }
+ ErrorF("VBESaveRestore done with success\n");
+ return;
+ }
+ ErrorF("VBESaveRestore done\n");
+ }
+
+ if (function == MODE_SAVE && !SaveSucc)
+ (void)VBEGetVBEMode(pVbe, &vbe_sr->stateMode);
+
+ if (function == MODE_RESTORE && vbe_sr->stateMode != -1)
+ VBESetVBEMode(pVbe, vbe_sr->stateMode, NULL);
+
+}
+
+int
+VBEGetPixelClock(vbeInfoPtr pVbe, int mode, int clock)
+{
+ /*
+ Input:
+ AX := 4F0Bh VBE Get Pixel Clock
+ BL := 00h Get Pixel Clock
+ ECX := pixel clock in units of Hz
+ DX := mode number
+
+ Output:
+ AX := VBE Return Status
+ ECX := Closest pixel clock
+ */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f0b;
+ pVbe->pInt10->bx = 0x00;
+ pVbe->pInt10->cx = clock;
+ pVbe->pInt10->dx = mode;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return 0;
+
+ return pVbe->pInt10->cx;
+}
+
+Bool
+VBEDPMSSet(vbeInfoPtr pVbe, int mode)
+{
+ /*
+ Input:
+ AX := 4F10h DPMS
+ BL := 01h Set Display Power State
+ BH := requested power state
+
+ Output:
+ AX := VBE Return Status
+ */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f10;
+ pVbe->pInt10->bx = 0x01;
+ switch (mode) {
+ case DPMSModeOn:
+ break;
+ case DPMSModeStandby:
+ pVbe->pInt10->bx |= 0x100;
+ break;
+ case DPMSModeSuspend:
+ pVbe->pInt10->bx |= 0x200;
+ break;
+ case DPMSModeOff:
+ pVbe->pInt10->bx |= 0x400;
+ break;
+ }
+ xf86ExecX86int10(pVbe->pInt10);
+ return (R16(pVbe->pInt10->ax) == 0x4f);
+}
+
+void
+VBEInterpretPanelID(int scrnIndex, struct vbePanelID *data)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ DisplayModePtr mode;
+ const float PANEL_HZ = 60.0;
+
+ if (!data)
+ return;
+
+ xf86DrvMsg(scrnIndex, X_INFO, "PanelID returned panel resolution %dx%d\n",
+ data->hsize, data->vsize);
+
+ if (pScrn->monitor->nHsync || pScrn->monitor->nVrefresh)
+ return;
+
+ if (data->hsize < 320 || data->vsize < 240) {
+ xf86DrvMsg(scrnIndex, X_INFO, "...which I refuse to believe\n");
+ return;
+ }
+
+ mode = xf86CVTMode(data->hsize, data->vsize, PANEL_HZ, 1, 0);
+
+ pScrn->monitor->nHsync = 1;
+ pScrn->monitor->hsync[0].lo = 31.5;
+ pScrn->monitor->hsync[0].hi = (float)mode->Clock / (float)mode->HTotal;
+ pScrn->monitor->nVrefresh = 1;
+ pScrn->monitor->vrefresh[0].lo = 56.0;
+ pScrn->monitor->vrefresh[0].hi =
+ (float)mode->Clock*1000.0 / (float)mode->HTotal / (float)mode->VTotal;
+
+ free(mode);
+}
+
+struct vbePanelID *
+VBEReadPanelID(vbeInfoPtr pVbe)
+{
+ int RealOff = pVbe->real_mode_base;
+ pointer page = pVbe->memory;
+ void *tmp = NULL;
+ int screen = pVbe->pInt10->scrnIndex;
+
+ pVbe->pInt10->ax = 0x4F11;
+ pVbe->pInt10->bx = 0x01;
+ pVbe->pInt10->cx = 0;
+ pVbe->pInt10->dx = 0;
+ pVbe->pInt10->es = SEG_ADDR(RealOff);
+ pVbe->pInt10->di = SEG_OFF(RealOff);
+ pVbe->pInt10->num = 0x10;
+
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID invalid\n");
+ goto error;
+ }
+
+ switch (pVbe->pInt10->ax & 0xff00) {
+ case 0x0:
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read successfully\n");
+ tmp = xnfalloc(32);
+ memcpy(tmp, page, 32);
+ break;
+ case 0x100:
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read failed\n");
+ break;
+ default:
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID unknown failure %i\n",
+ pVbe->pInt10->ax & 0xff00);
+ break;
+ }
+
+error:
+ return tmp;
+}