Files
nv-xconfig/nvidia-xconfig-540.4.0/XF86Config-parser/Generate.c
svcmobrel-release 793d53d490 Updating prebuilts and/or headers
b1bc157844c5570f911b2bf45249bd26ce73efef - nvidia-xconfig-540.4.0/Makefile
4cc77b90af91e615a64ae04893fdffa7939db84c - nvidia-xconfig-540.4.0/COPYING
f14e9577e537037d4778d490ef70f13b0e94a70a - nvidia-xconfig-540.4.0/option_table.h
647e7896275a1113ec99352d573823a05001f57e - nvidia-xconfig-540.4.0/lscf.c
1e39095238886dfc6a69f7ec750e10c05a93e7d1 - nvidia-xconfig-540.4.0/nvidia-xconfig.1.m4
a5ad539267b73169480e7898b284823639c4db3a - nvidia-xconfig-540.4.0/tree.c
b3d0f9f27c4d9cb7940d04e1dd387d357a16024c - nvidia-xconfig-540.4.0/nvidia-xconfig.c
46f2ea329459b0b16cb36cc14cec0de737d0963e - nvidia-xconfig-540.4.0/options.c
6f6f68f976250f2646450e571f9ab2d7eee1ac80 - nvidia-xconfig-540.4.0/nvidia-cfg.h
913b088cb559f31e09a1baf89d85d75cb43079b4 - nvidia-xconfig-540.4.0/nvidia-xconfig.h
bfa37f78ba458f14a1865bbf3f67eb84987a7e1c - nvidia-xconfig-540.4.0/extract_edids.c
d37da5a118e0418b267a48d05fd144611316b42c - nvidia-xconfig-540.4.0/gen-manpage-opts.c
41bcac41393c9a465c30c07cf1ab386647a16687 - nvidia-xconfig-540.4.0/util.c
9b0c02164398be2795fea7cb13c9e1b062d24bfb - nvidia-xconfig-540.4.0/query_gpu_info.c
c946eefad99cec9366d8abbd4e45c5d138d3b7be - nvidia-xconfig-540.4.0/make_usable.c
10edc2c301fd331439b38d001c0df41669c238b2 - nvidia-xconfig-540.4.0/multiple_screens.c
c7b8d8ca0f7c9dcc2cdca4f8e77d1122c71892ef - nvidia-xconfig-540.4.0/XF86Config-parser/Read.c
a9bc06f33bf525c2b08be2dc3cd64a59c4c7946d - nvidia-xconfig-540.4.0/XF86Config-parser/Configint.h
2022a4a3c2a1b23a67ae74f50a3849f5f3a45e4b - nvidia-xconfig-540.4.0/XF86Config-parser/Keyboard.c
83b0a8efd6a508db54995688ab353591bdb242a2 - nvidia-xconfig-540.4.0/XF86Config-parser/Flags.c
e67d630ef396ab7d34524c333f3a77fc42ba8fc6 - nvidia-xconfig-540.4.0/XF86Config-parser/configProcs.h
f3d611bdbddfa64675a0810ef81dada57e224bcd - nvidia-xconfig-540.4.0/XF86Config-parser/Extensions.c
5ffb2caa5077a2e6ec1c5ece807e71503fb2fbce - nvidia-xconfig-540.4.0/XF86Config-parser/Module.c
7344be997921dec57959691e986763ee686888d5 - nvidia-xconfig-540.4.0/XF86Config-parser/Device.c
33211ca0a10f50e2c87b9e8feef6c1ab381b57a1 - nvidia-xconfig-540.4.0/XF86Config-parser/DRI.c
953b945f3b117d6fb44f1f738af17b6380a9ec72 - nvidia-xconfig-540.4.0/XF86Config-parser/Monitor.c
6c210ad0eaee1db3fec48ff01746cb054b4f9aaa - nvidia-xconfig-540.4.0/XF86Config-parser/Video.c
4407207cf890539dc604cff5b834c994b307729a - nvidia-xconfig-540.4.0/XF86Config-parser/Write.c
de1c758e29f217e1a99e4c076d54ac84bce98b18 - nvidia-xconfig-540.4.0/XF86Config-parser/Screen.c
c66a0a141e25e31b568fb9df41f17d7fb9e6d3b9 - nvidia-xconfig-540.4.0/XF86Config-parser/xf86Parser.h
9cbc29da282aa957f28b7fc83caf1e3b19ee2a52 - nvidia-xconfig-540.4.0/XF86Config-parser/Vendor.c
18711ff932af2202869a30f3b32d6d7fe7811c84 - nvidia-xconfig-540.4.0/XF86Config-parser/Layout.c
cda3a4ab05bf48ba28af35b5c4c632e968afc7fa - nvidia-xconfig-540.4.0/XF86Config-parser/Util.c
ec19d673a6a7d1d8f855f2d32d3e8f63046c3625 - nvidia-xconfig-540.4.0/XF86Config-parser/Files.c
ac878b26ded86a3c502a6a81fc4c4a96162afefb - nvidia-xconfig-540.4.0/XF86Config-parser/Merge.c
0a274c4bc54b6ae0f6d009e443bda0cb033d66b5 - nvidia-xconfig-540.4.0/XF86Config-parser/Pointer.c
3f2238c88d737bd329a9bca1ac4b0bcf77bb9ac2 - nvidia-xconfig-540.4.0/XF86Config-parser/xf86tokens.h
45ceb0129668346ae3e52d81bb6e2f97efadf9d0 - nvidia-xconfig-540.4.0/XF86Config-parser/Input.c
4d9b03ea3badceb6bdfdf6589e6731140ec44079 - nvidia-xconfig-540.4.0/XF86Config-parser/Generate.c
04efe162cf6d97882f2bb87f3712d9a65c2320f3 - nvidia-xconfig-540.4.0/XF86Config-parser/Scan.c
5d55b94375c2055cfa1578e4c7f34c90e63a33f7 - nvidia-xconfig-540.4.0/common-utils/gen-manpage-opts-helper.c
384e36102dcd08ed4c5de05b5e3b8a7cdb2e257d - nvidia-xconfig-540.4.0/common-utils/nvgetopt.c
dc2678d8a9d794a4b2b2718fce57ec087f21f54b - nvidia-xconfig-540.4.0/common-utils/common-utils.h
8db48a58d1654ed69920366bef10f38b789a1a84 - nvidia-xconfig-540.4.0/common-utils/msg.c
e572cac43202f6c2af1c80b9e3901215126093ed - nvidia-xconfig-540.4.0/common-utils/nvgetopt.h
8a346196b052cfb1e06dd83d2ad1fe71e928d2b3 - nvidia-xconfig-540.4.0/common-utils/common-utils.c
1654638c567bc7f2bd70b54d807b498ab14c1061 - nvidia-xconfig-540.4.0/common-utils/nvpci-utils.h
8259a24058c714629f9819cc8c830ea9b202bb27 - nvidia-xconfig-540.4.0/common-utils/gen-manpage-opts-helper.h
524990f5497f9bbeb3d148b5e7dc8d2267c3163d - nvidia-xconfig-540.4.0/common-utils/nvpci-utils.c
abb5c1b445d9353f2d2840bda848cd16109710a4 - nvidia-xconfig-540.4.0/common-utils/msg.h

Change-Id: I923b8a9c53e3923f3261fb29c72380b5a1f7ab3e
2024-09-27 12:48:41 -07:00

1492 lines
47 KiB
C

/*
* nvidia-xconfig: A tool for manipulating X config files,
* specifically for use by the NVIDIA Linux graphics driver.
*
* Copyright (C) 2005 NVIDIA Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses>.
*
*
* Generate.c
*/
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include "xf86Parser.h"
#include "Configint.h"
#define MOUSE_IDENTIFER "Mouse0"
#define KEYBOARD_IDENTIFER "Keyboard0"
#define SCREEN_IDENTIFIER "Screen%d"
#define DEVICE_IDENTIFIER "%sDevice%d"
#define MONITOR_IDENTIFIER "Monitor%d"
static int is_file(const char *filename);
static void add_font_path(GenerateOptions *gop, XConfigPtr config);
static void add_modules(GenerateOptions *gop, XConfigPtr config);
static void add_layout(GenerateOptions *gop, XConfigPtr config);
static void add_inputref(XConfigPtr config, XConfigLayoutPtr layout,
char *name, char *coreKeyword);
/*
* xconfigGenerate() - generate a new XConfig from scratch
*/
XConfigPtr xconfigGenerate(GenerateOptions *gop)
{
XConfigPtr config;
config = xconfigAlloc(sizeof(XConfigRec));
/* add files, fonts, and modules */
config->files = xconfigAlloc(sizeof(XConfigFilesRec));
add_font_path(gop, config);
add_modules(gop, config);
/* add the keyboard and mouse */
xconfigAddKeyboard(gop, config);
xconfigAddMouse(gop, config);
/* add the layout */
add_layout(gop, config);
return config;
} /* xconfigGenerate() */
/*
* xconfigGenerateAddScreen() - add a new screen to the config; bus
* and slot can be -1 to be ignored; boardname can be NULL to be
* ignored; count is used when building the identifier name, eg
* '"Screen%d", count'. Note that this does not append the screen to
* any layout's adjacency list.
*/
XConfigScreenPtr xconfigGenerateAddScreen(XConfigPtr config,
int bus, int domain, int slot,
char *boardname, int count,
const char *driver,
const char *vendor)
{
XConfigScreenPtr screen, s;
XConfigDevicePtr device;
XConfigMonitorPtr monitor;
monitor = xconfigAddMonitor(config, count);
device = add_device(config, bus, domain, slot, boardname, count,
driver, vendor, TRUE /* active */);
screen = xconfigAlloc(sizeof(XConfigScreenRec));
screen->identifier = xconfigAlloc(32);
snprintf(screen->identifier, 32, SCREEN_IDENTIFIER, count);
screen->device_name = xconfigStrdup(device->identifier);
screen->device = device;
screen->monitor_name = xconfigStrdup(monitor->identifier);
screen->monitor = monitor;
screen->defaultdepth = 24;
xconfigAddDisplay(&screen->displays, screen->defaultdepth);
/* append to the end of the screen list */
if (!config->screens) {
config->screens = screen;
} else {
for (s = config->screens; s->next; s = s->next);
s->next = screen;
}
return screen;
} /* xconfigGenerateAddScreen() */
/*
* xconfigGenerateAssignScreenAdjacencies() - setup all the adjacency
* information for the X screens in the given layout. Nothing fancy
* here: just position all the screens horizontally, moving from left
* to right.
*/
void xconfigGenerateAssignScreenAdjacencies(XConfigLayoutPtr layout)
{
XConfigAdjacencyPtr adj, prev = NULL;
for (adj = layout->adjacencies; adj; adj = adj->next) {
if (prev) {
adj->where = CONF_ADJ_RIGHTOF;
adj->refscreen = xconfigStrdup(prev->screen_name);
} else {
adj->x = adj->y = -1;
}
/* make sure all the obsolete positioning is empty */
adj->top = NULL;
adj->top_name = NULL;
adj->bottom = NULL;
adj->bottom_name = NULL;
adj->left = NULL;
adj->left_name = NULL;
adj->right = NULL;
adj->right_name = NULL;
prev = adj;
}
} /* xconfigGenerateAssignScreenAdjacencies() */
/*********************************************************************/
/*
* is_file()
*/
static int is_file(const char *filename)
{
return (access(filename, F_OK) == 0);
} /* is_file() */
/*
* find_libdir() - attempt to find the X server library path; this is
* either
*
* `pkg-config --variable=libdir xorg-server`
*
* or
*
* [X PROJECT ROOT]/lib
*/
static char *find_libdir(GenerateOptions *gop)
{
struct stat stat_buf;
FILE *stream = NULL;
char *s, *libdir = NULL;
/*
* run the pkg-config command and read the output; if the output
* is a directory, then return that as the libdir
*/
stream = popen("pkg-config --variable=libdir xorg-server", "r");
if (stream) {
char buf[256];
buf[0] = '\0';
while (1) {
if (fgets(buf, 255, stream) == NULL) break;
if (buf[0] != '\0') {
/* truncate any newline */
s = strchr(buf, '\n');
if (s) *s = '\0';
if ((stat(buf, &stat_buf) == 0) &&
(S_ISDIR(stat_buf.st_mode))) {
libdir = xconfigStrdup(buf);
break;
}
}
}
pclose(stream);
if (libdir) return libdir;
}
/* otherwise, just fallback to [X PROJECT ROOT]/lib */
return xconfigStrcat(gop->x_project_root, "/lib", NULL);
} /* find_libdir() */
/*
* add_font_path() - scan through the __font_paths[] array,
* temporarily chop off the ":unscaled" appendage, and check for the
* file "fonts.dir" in the directory. If fonts.dir exists, append the
* path to config->files->fontpath.
*/
static void add_font_path(GenerateOptions *gop, XConfigPtr config)
{
int i, ret;
char *path, *p, *orig, *fonts_dir, *libdir;
/*
* The below font path has been constructed from various examples
* and uses some suggests from the Font De-uglification HOWTO
*/
static const char *__font_paths[] = {
"LIBDIR/X11/fonts/local/",
"LIBDIR/X11/fonts/misc/:unscaled",
"LIBDIR/X11/fonts/100dpi/:unscaled",
"LIBDIR/X11/fonts/75dpi/:unscaled",
"LIBDIR/X11/fonts/misc/",
"LIBDIR/X11/fonts/Type1/",
"LIBDIR/X11/fonts/CID/",
"LIBDIR/X11/fonts/Speedo/",
"LIBDIR/X11/fonts/100dpi/",
"LIBDIR/X11/fonts/75dpi/",
"LIBDIR/X11/fonts/cyrillic/",
"LIBDIR/X11/fonts/TTF/",
"LIBDIR/X11/fonts/truetype/",
"LIBDIR/X11/fonts/TrueType/",
"LIBDIR/X11/fonts/Type1/sun/",
"LIBDIR/X11/fonts/F3bitmaps/",
"/usr/local/share/fonts/ttfonts",
"/usr/share/fonts/default/Type1",
"/usr/lib/openoffice/share/fonts/truetype",
NULL
};
/*
* if a font server is running, set the font path to that
*
* XXX should we check the port the font server is using?
*/
#if defined(NV_SUNOS)
ret = system("ps -e -o fname | grep -v grep | egrep \"^xfs$\" > /dev/null");
#elif defined(NV_BSD)
ret = system("ps -e -o comm | grep -v grep | egrep \"^xfs$\" > /dev/null");
#else
ret = system("ps -C xfs 2>&1 > /dev/null");
#endif
if (WEXITSTATUS(ret) == 0) {
config->files->fontpath = xconfigStrdup("unix/:7100");
} else {
/* get the X server libdir */
libdir = find_libdir(gop);
for (i = 0; __font_paths[i]; i++) {
path = xconfigStrdup(__font_paths[i]);
/* replace LIBDIR with libdir */
if (strncmp(path, "LIBDIR", 6) == 0) {
p = xconfigStrcat(libdir, path + 6, NULL);
free(path);
path = p;
}
/* temporarily chop off any ":unscaled" appendage */
p = strchr(path, ':');
if (p) *p = '\0';
/* skip this entry if the fonts.dir does not exist */
fonts_dir = xconfigStrcat(path, "/fonts.dir", NULL);
if (!is_file(fonts_dir)) {
/* does not exist */
free(path);
free(fonts_dir);
continue;
}
free(fonts_dir);
/* add the ":unscaled" back */
if (p) *p = ':';
/*
* either use this path as the fontpath, or append to the
* existing fontpath
*/
if (config->files->fontpath) {
orig = config->files->fontpath;
config->files->fontpath = xconfigStrcat(orig, ",", path, NULL);
free(orig);
free(path);
} else {
config->files->fontpath = path;
}
}
/* free the libdir string */
free(libdir);
}
} /* add_font_path() */
/*
* add_modules()
*/
static void add_modules(GenerateOptions *gop, XConfigPtr config)
{
XConfigLoadPtr l = NULL;
/*
* if the X server will automatically autoload GLX, then don't
* bother adding a modules section; it is difficult for
* nvidia-xconfig to know if modules like "type1" are present,
* anyway.
*/
if (gop->autoloads_glx) return;
config->modules = xconfigAlloc(sizeof(XConfigModuleRec));
xconfigAddNewLoadDirective(&l, xconfigStrdup("dbe"),
XCONFIG_LOAD_MODULE, NULL, FALSE);
xconfigAddNewLoadDirective(&l, xconfigStrdup("extmod"),
XCONFIG_LOAD_MODULE, NULL, FALSE);
xconfigAddNewLoadDirective(&l, xconfigStrdup("type1"),
XCONFIG_LOAD_MODULE, NULL, FALSE);
#if defined(NV_SUNOS)
xconfigAddNewLoadDirective(&l, xconfigStrdup("IA"),
XCONFIG_LOAD_MODULE, NULL, FALSE);
xconfigAddNewLoadDirective(&l, xconfigStrdup("bitstream"),
XCONFIG_LOAD_MODULE, NULL, FALSE);
xconfigAddNewLoadDirective(&l, xconfigStrdup("xtsol"),
XCONFIG_LOAD_MODULE, NULL, FALSE);
#else
xconfigAddNewLoadDirective(&l, xconfigStrdup("freetype"),
XCONFIG_LOAD_MODULE, NULL, FALSE);
#endif
xconfigAddNewLoadDirective(&l, xconfigStrdup("glx"),
XCONFIG_LOAD_MODULE, NULL, FALSE);
config->modules->loads = l;
} /* add_modules() */
/*
* xconfigAddMonitor() -
*
* XXX pass EDID values into this...
*/
XConfigMonitorPtr xconfigAddMonitor(XConfigPtr config, int count)
{
XConfigMonitorPtr monitor, m;
/* XXX need to query resman for the EDID */
monitor = xconfigAlloc(sizeof(XConfigMonitorRec));
monitor->identifier = xconfigAlloc(32);
snprintf(monitor->identifier, 32, MONITOR_IDENTIFIER, count);
monitor->vendor = xconfigStrdup("Unknown"); /* XXX */
monitor->modelname = xconfigStrdup("Unknown"); /* XXX */
monitor->options = NULL;
xconfigAddNewOption(&monitor->options, "DPMS", NULL);
/* append to the end of the monitor list */
if (!config->monitors) {
config->monitors = monitor;
} else {
for (m = config->monitors; m->next; m = m->next);
m->next = monitor;
}
return monitor;
} /* xconfigAddMonitor() */
/*
* add_device()
*/
XConfigDevicePtr add_device(XConfigPtr config, int bus, int domain,
int slot, char *boardname, int count,
const char *driver, const char *vendor, int active)
{
XConfigDevicePtr device, d;
device = xconfigAlloc(sizeof(XConfigDeviceRec));
device->identifier = xconfigAlloc(32);
snprintf(device->identifier, 32, DEVICE_IDENTIFIER,
active ? "" : "Inactive", count);
device->index_id = count;
device->driver = xconfigStrdup(driver);
device->vendor = xconfigStrdup(vendor);
if (bus != -1 && domain != -1 && slot != -1) {
device->busid = xconfigAlloc(32);
xconfigFormatPciBusString(device->busid, 32, domain, bus, slot, 0);
}
if (boardname) device->board = xconfigStrdup(boardname);
device->chipid = -1;
device->chiprev = -1;
device->irq = -1;
device->screen = -1;
/* append to the end of the device list */
if (!config->devices) {
config->devices = device;
} else {
for (d = config->devices; d->next; d = d->next);
d->next = device;
}
return device;
} /* add_device() */
void xconfigAddDisplay(XConfigDisplayPtr *pHead, const int depth)
{
XConfigDisplayPtr display;
display = xconfigAlloc(sizeof(XConfigDisplayRec));
display->depth = depth;
display->modes = NULL;
display->frameX0 = -1;
display->frameY0 = -1;
display->black.red = -1;
display->white.red = -1;
display->next = *pHead;
*pHead = display;
}
/*
* add_layout() - add a layout section to the XConfigPtr
*/
static void add_layout(GenerateOptions *gop, XConfigPtr config)
{
XConfigLayoutPtr layout;
XConfigAdjacencyPtr adj;
XConfigScreenPtr screen;
/* assume 1 X screen */
screen = xconfigGenerateAddScreen(config, -1, -1, -1, NULL, 0,
"nvidia", "NVIDIA Corporation");
/* create layout */
layout = xconfigAlloc(sizeof(XConfigLayoutRec));
layout->identifier = xconfigStrdup("Layout0");
adj = xconfigAlloc(sizeof(XConfigAdjacencyRec));
adj->scrnum = 0;
adj->screen = screen;
adj->screen_name = xconfigStrdup(screen->identifier);
layout->adjacencies = adj;
xconfigGenerateAssignScreenAdjacencies(layout);
add_inputref(config, layout, MOUSE_IDENTIFER, "CorePointer");
add_inputref(config, layout, KEYBOARD_IDENTIFER, "CoreKeyboard");
layout->next = config->layouts;
config->layouts = layout;
} /* add_layout() */
/*
* add_inputref() - add a new XConfigInputrefPtr to the given layout
*/
static void add_inputref(XConfigPtr config, XConfigLayoutPtr layout,
char *name, char *coreKeyword)
{
XConfigInputrefPtr inputRef;
inputRef = xconfigAlloc(sizeof(XConfigInputrefRec));
inputRef->input_name = xconfigStrdup(name);
inputRef->input = xconfigFindInput(inputRef->input_name, config->inputs);
inputRef->options = NULL;
xconfigAddNewOption(&inputRef->options, coreKeyword, NULL);
inputRef->next = layout->inputs;
layout->inputs = inputRef;
} /* add_inputref() */
/*********************************************************************/
/*
* Mouse detection
*/
typedef struct {
char *shortname; /* commandline name */
char *name; /* mouse name */
char *gpmproto; /* protocol used by gpm */
char *Xproto; /* XFree86 Protocol */
char *device; /* /dev/ file */
int emulate3; /* Emulate3Buttons */
} MouseEntry;
/*
* This table is based on data contained in
* /usr/lib/python2.2/site-packages/rhpl/mouse.py on Red Hat Fedora
* core 1. That file contains the following copyright:
*
*
* mouse.py: mouse configuration data
*
* Copyright 1999-2002 Red Hat, Inc.
*/
static const MouseEntry __mice[] = {
/* shortname name gpm protocol X protocol device emulate3 */
{ "alpsps/2", "ALPS - GlidePoint (PS/2)", "ps/2", "GlidePointPS/2", "psaux", TRUE },
{ "ascii", "ASCII - MieMouse (serial)", "ms3", "IntelliMouse", "ttyS", FALSE },
{ "asciips/2", "ASCII - MieMouse (PS/2)", "ps/2", "NetMousePS/2", "psaux", TRUE },
{ "atibm", "ATI - Bus Mouse", "Busmouse", "BusMouse", "atibm", TRUE },
{ "generic", "Generic - 2 Button Mouse (serial)", "Microsoft", "Microsoft", "ttyS", TRUE },
{ "generic3", "Generic - 3 Button Mouse (serial)", "Microsoft", "Microsoft", "ttyS", FALSE },
{ "genericps/2", "Generic - 2 Button Mouse (PS/2)", "ps/2", "PS/2", "psaux", TRUE },
{ "generic3ps/2", "Generic - 3 Button Mouse (PS/2)", "ps/2", "PS/2", "psaux", FALSE },
{ "genericwheelps/2", "Generic - Wheel Mouse (PS/2)", "imps2", "IMPS/2", "psaux", FALSE },
{ "genericusb", "Generic - 2 Button Mouse (USB)", "imps2", "IMPS/2", "input/mice", TRUE },
{ "generic3usb", "Generic - 3 Button Mouse (USB)", "imps2", "IMPS/2", "input/mice", FALSE },
{ "genericwheelusb", "Generic - Wheel Mouse (USB)", "imps2", "IMPS/2", "input/mice", FALSE },
{ "geniusnm", "Genius - NetMouse (serial)", "ms3", "IntelliMouse", "ttyS", TRUE },
{ "geniusnmps/2", "Genius - NetMouse (PS/2)", "netmouse", "NetMousePS/2", "psaux", TRUE },
{ "geniusprops/2", "Genius - NetMouse Pro (PS/2)", "netmouse", "NetMousePS/2", "psaux", TRUE },
{ "geniusscrollps/2", "Genius - NetScroll (PS/2)", "netmouse", "NetScrollPS/2", "psaux", TRUE },
{ "geniusscrollps/2+", "Genius - NetScroll+ (PS/2)", "netmouse", "NetMousePS/2", "psaux", FALSE },
{ "thinking", "Kensington - Thinking Mouse (serial)", "Microsoft", "ThinkingMouse", "ttyS", TRUE },
{ "thinkingps/2", "Kensington - Thinking Mouse (PS/2)", "ps/2", "ThinkingMousePS/2", "psaux", TRUE },
{ "logitech", "Logitech - C7 Mouse (serial, old C7 type)", "Logitech", "Logitech", "ttyS", FALSE },
{ "logitechcc", "Logitech - CC Series (serial)", "logim", "MouseMan", "ttyS", FALSE },
{ "logibm", "Logitech - Bus Mouse", "Busmouse", "BusMouse", "logibm", FALSE },
{ "logimman", "Logitech - MouseMan/FirstMouse (serial)", "MouseMan", "MouseMan", "ttyS", FALSE },
{ "logimmanps/2", "Logitech - MouseMan/FirstMouse (PS/2)", "ps/2", "PS/2", "psaux", FALSE },
{ "logimman+", "Logitech - MouseMan+/FirstMouse+ (serial)", "pnp", "IntelliMouse", "ttyS", FALSE },
{ "logimman+ps/2", "Logitech - MouseMan+/FirstMouse+ (PS/2)", "ps/2", "MouseManPlusPS/2", "psaux", FALSE },
{ "logimmusb", "Logitech - MouseMan Wheel (USB)", "ps/2", "IMPS/2", "input/mice", FALSE },
{ "logimmusboptical", "Logitech - Cordless Optical Mouse (USB)", "ps/2", "IMPS/2", "input/mice", FALSE },
{ "microsoft", "Microsoft - Compatible Mouse (serial)", "Microsoft", "Microsoft", "ttyS", TRUE },
{ "msnew", "Microsoft - Rev 2.1A or higher (serial)", "pnp", "Auto", "ttyS", TRUE },
{ "msintelli", "Microsoft - IntelliMouse (serial)", "ms3", "IntelliMouse", "ttyS", FALSE },
{ "msintellips/2", "Microsoft - IntelliMouse (PS/2)", "imps2", "IMPS/2", "psaux", FALSE },
{ "msintelliusb", "Microsoft - IntelliMouse (USB)", "ps/2", "IMPS/2", "input/mice", FALSE },
{ "msintelliusboptical","Microsoft - IntelliMouse Optical (USB)", "ps/2", "IMPS/2", "input/mice", FALSE },
{ "msbm", "Microsoft - Bus Mouse", "Busmouse", "BusMouse", "inportbm", TRUE },
{ "mousesystems", "Mouse Systems - Mouse (serial)", "MouseSystems", "MouseSystems", "ttyS", TRUE },
{ "mmseries", "MM - Series (serial)", "MMSeries", "MMSeries", "ttyS", TRUE },
{ "mmhittab", "MM - HitTablet (serial)", "MMHitTab", "MMHittab", "ttyS", TRUE },
{ "sun", "Sun - Mouse", "sun", "sun", "sunmouse", FALSE },
{ NULL, NULL, NULL, NULL, NULL, FALSE },
};
/*
* This table maps between the mouse protocol name used for gpm and
* for the X server "protocol" mouse option.
*/
typedef struct {
char *gpmproto;
char *Xproto;
} ProtocolEntry;
static const ProtocolEntry __protocols[] = {
/* gpm protocol X protocol */
{ "ms3", "IntelliMouse" },
{ "Busmouse", "BusMouse" },
{ "Microsoft", "Microsoft" },
{ "imps2", "IMPS/2" },
{ "netmouse", "NetMousePS/2" },
{ "Logitech", "Logitech" },
{ "logim", "MouseMan" },
{ "MouseMan", "MouseMan" },
{ "ps/2", "PS/2" },
{ "pnp", "Auto" },
{ "MouseSystems", "MouseSystems" },
{ "MMSeries", "MMSeries" },
{ "MMHitTab", "MMHittab" },
{ "sun", "sun" },
{ NULL, NULL },
};
/*
* gpm_proto_to_X_proto() - map from gpm mouse protocol to X mouse
* protocol
*/
static char* gpm_proto_to_X_proto(const char *gpm)
{
int i;
for (i = 0; __protocols[i].gpmproto; i++) {
if (strcmp(gpm, __protocols[i].gpmproto) == 0) {
return __protocols[i].Xproto;
}
}
return NULL;
} /* gpm_proto_to_X_proto() */
/*
* find_mouse_entry() - scan the __mice[] table for the entry that
* corresponds to the specified value; return a pointer to the
* matching entry in the table, if any.
*/
static const MouseEntry *find_mouse_entry(char *value)
{
int i;
if (!value) return NULL;
for (i = 0; __mice[i].name; i++) {
if (strcmp(value, __mice[i].shortname) == 0) {
return &__mice[i];
}
}
return NULL;
} /* find_mouse_entry() */
/*
* find_closest_mouse_entry() - scan the __mice[] table for the entry that
* matches all of the specified values; any of the values can be NULL,
* in which case we do not use them as part of the comparison. Note
* that device is compared case sensitive, proto is compared case
* insensitive, and emulate3 is just a boolean.
*/
static const MouseEntry *find_closest_mouse_entry(const char *device,
const char *proto,
const char *emulate3_str)
{
int i;
int emulate3 = FALSE;
/*
* translate the emulate3 string into a boolean we can use below
* for comparison
*/
if ((emulate3_str) &&
((strcasecmp(emulate3_str, "yes") == 0) ||
(strcasecmp(emulate3_str, "true") == 0) ||
(strcasecmp(emulate3_str, "1") == 0))) {
emulate3 = TRUE;
}
/*
* skip the "/dev/" part of the device filename
*/
if (device && (strncmp(device, "/dev/", 5) == 0)) {
device += 5; /* strlen("/dev/") */
}
for (i = 0; __mice[i].name; i++) {
if ((device) && (strcmp(device, __mice[i].device) != 0)) continue;
if ((proto) && (strcasecmp(proto, __mice[i].Xproto)) != 0) continue;
if ((emulate3_str) && (emulate3 != __mice[i].emulate3)) continue;
return &__mice[i];
}
return NULL;
} /* find_closest_mouse_entry() */
/*
* find_config_entry() - scan the specified filename for the specified
* keyword; return the value that the keyword is assigned to, or NULL
* if any error occurs.
*/
static char *find_config_entry(const char *filename, const char *keyword)
{
int fd = -1;
char *data = NULL;
char *value = NULL;
char *buf = NULL;
char *tmp, *start, *c, *end;
struct stat stat_buf;
size_t len;
if ((fd = open(filename, O_RDONLY)) == -1) goto done;
if (fstat(fd, &stat_buf) == -1) goto done;
if ((data = mmap(0, stat_buf.st_size, PROT_READ, MAP_SHARED,
fd, 0)) == (void *) -1) goto done;
/*
* create a sysmem copy of the buffer, so that we can explicitly
* NULL terminate it
*/
buf = malloc(stat_buf.st_size + 1);
if (!buf) goto done;
memcpy(buf, data, stat_buf.st_size);
buf[stat_buf.st_size] = '\0';
/* search for the keyword */
start = buf;
while (TRUE) {
tmp = strstr(start, keyword);
if (!tmp) goto done;
/*
* make sure this line is not commented out: search back from
* tmp: if we hit a "#" before a newline, then this line is
* commented out and we should search again
*/
c = tmp;
while ((c >= start) && (*c != '\n') && (*c != '#')) c--;
if (*c == '#') {
/* keyword was commented out... search again */
start = tmp+1;
} else {
/* keyword is not commented out */
break;
}
}
start = tmp + strlen(keyword);
end = strchr(start, '\n');
if (!end) goto done;
/* there must be something between the start and the end */
if (start == end) goto done;
/* take what is between as the value */
len = end - start;
value = xconfigAlloc(len + 1);
strncpy(value, start, len);
value[len] = '\0';
/* if the first and last characters are quotation marks, remove them */
if ((value[0] == '\"') && (value[len-1] == '\"')) {
tmp = xconfigAlloc(len - 1);
strncpy(tmp, value + 1, len - 2);
tmp[len-2] = '\0';
free(value);
value = tmp;
}
done:
if (buf) free(buf);
if (data) munmap(data, stat_buf.st_size);
if (fd != -1) close(fd);
return value;
} /* find_config_entry() */
/*
* xconfigGeneratePrintPossibleMice() - print the mouse table to stdout
*/
void xconfigGeneratePrintPossibleMice(void)
{
int i;
printf("%-25s%-35s\n\n", "Short Name", "Name");
for (i = 0; __mice[i].name; i++) {
printf("%-25s%-35s\n", __mice[i].shortname, __mice[i].name);
}
printf("\n");
} /* xconfigGeneratePrintPossibleMice() */
/*
* xconfigAddMouse() - determine the mouse type, and then add an
* XConfigInputRec with the appropriate options.
*
* - if the user specified on the commandline, use that
*
* - if /etc/sysconfig/mouse exists and contains valid data, use
* that
*
* - if /etc/conf.d/gpm exists and contains valid data, use that
*
* - infer the settings from the commandline options gpm is using XXX?
*
* - default to "auto" on /dev/mouse
*/
int xconfigAddMouse(GenerateOptions *gop, XConfigPtr config)
{
const MouseEntry *entry = NULL;
XConfigInputPtr input;
char *device_path, *comment = "default";
/* if the user specified on the commandline, use that */
if (gop->mouse) {
entry = find_mouse_entry(gop->mouse);
if (entry) {
comment = "commandline input";
} else {
xconfigErrorMsg(WarnMsg, "Unable to find mouse \"%s\".",
gop->mouse);
}
}
/*
* if /etc/sysconfig/mouse exists, and contains valid data, use
* that
*/
if (!entry) {
char *protocol, *device, *emulate3;
device = find_config_entry("/etc/sysconfig/mouse", "DEVICE=");
protocol = find_config_entry("/etc/sysconfig/mouse", "XMOUSETYPE=");
emulate3 = find_config_entry("/etc/sysconfig/mouse", "XEMU3=");
if (device || protocol || emulate3) {
entry = find_closest_mouse_entry(device, protocol, emulate3);
if (entry) {
comment = "data in \"/etc/sysconfig/mouse\"";
}
}
}
/* if /etc/conf.d/gpm exists and contains valid data, use that */
if (!entry) {
char *protocol, *device;
protocol = find_config_entry("/etc/conf.d/gpm", "MOUSE=");
device = find_config_entry("/etc/conf.d/gpm", "MOUSEDEV=");
if (protocol && device) {
MouseEntry *e = xconfigAlloc(sizeof(MouseEntry));
e->shortname = "custom";
e->name = "inferred from /etc/conf.d/gpm";
e->gpmproto = protocol;
e->Xproto = gpm_proto_to_X_proto(protocol);
e->device = device + strlen("/dev/");
e->emulate3 = FALSE; // XXX?
entry = e;
comment = "data in \"/etc/conf.d/gpm\"";
}
}
/*
* XXX we could try to infer the settings from the commandline
* options gpm is using
*/
if (!entry) {
/* XXX implement me */
}
/* at this point, we must have a mouse entry */
if (!entry) {
MouseEntry *e = xconfigAlloc(sizeof(MouseEntry));
e->Xproto = "auto";
#if defined(NV_BSD)
e->device = "sysmouse";
#else
if (access("/dev/psaux", F_OK) == 0) {
e->device = "psaux";
} else if (access("/dev/input/mice", F_OK) == 0) {
e->device = "input/mice";
} else {
e->device = "mouse";
}
#endif
e->emulate3 = FALSE;
entry = e;
}
/* add a new mouse input section */
input = xconfigAlloc(sizeof(XConfigInputRec));
input->comment = xconfigStrcat(" # generated from ",
comment, "\n", NULL);
input->identifier = xconfigStrdup("Mouse0");
input->driver = xconfigStrdup("mouse");
device_path = xconfigStrcat("/dev/", entry->device, NULL);
input->options = NULL;
xconfigAddNewOption(&input->options, "Protocol", entry->Xproto);
xconfigAddNewOption(&input->options, "Device", device_path);
xconfigAddNewOption(&input->options, "Emulate3Buttons",
(entry->emulate3 ? "yes" : "no"));
TEST_FREE(device_path);
/*
* This will make wheel mice work, and non-wheel mice should
* ignore ZAxisMapping
*/
xconfigAddNewOption(&input->options, "ZAxisMapping", "4 5");
input->next = config->inputs;
config->inputs = input;
return TRUE;
} /* xconfigAddMouse() */
/*********************************************************************/
/*
* keyboard detection
*/
typedef struct {
char *keytable;
char *name;
char *layout; /* XkbLayout */
char *model; /* XkbModel */
char *variant; /* XkbVariant */
char *options; /* XkbOptions */
} KeyboardEntry;
/*
* This table is based on data contained in
* /usr/lib/python2.2/site-packages/rhpl/keyboard_models.py on Red Hat
* Fedora core 1. That file contains the following copyright:
*
*
* keyboard_models.py - keyboard model list
*
* Brent Fox <bfox@redhat.com>
* Mike Fulbright <msf@redhat.com>
* Jeremy Katz <katzj@redhat.com>
*
* Copyright 2002 Red Hat, Inc.
*/
static const KeyboardEntry __keyboards[] = {
/* keytable name layout model variant options */
{ "be-latin1", "Belgian (be-latin1)", "be", "pc105", NULL, NULL },
{ "bg", "Bulgarian", "bg,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" },
{ "br-abnt2", "Brazilian (ABNT2)", "br", "abnt2", NULL, NULL },
{ "cf", "French Canadian", "ca_enhanced", "pc105", NULL, NULL },
{ "croat", "Croatian", "hr", "pc105", NULL, NULL },
{ "cz-us-qwertz", "Czechoslovakian (qwertz)", "cz,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" },
{ "cz-lat2", "Czechoslovakian", "cz_qwerty", "pc105", NULL, NULL },
{ "de", "German", "de", "pc105", NULL, NULL },
{ "de-latin1", "German (latin1)", "de", "pc105", NULL, NULL },
{ "de-latin1-nodeadkeys", "German (latin1 w/ no deadkeys)", "de", "pc105", "nodeadkeys", NULL },
{ "dvorak", "Dvorak", "dvorak", "pc105", NULL, NULL },
{ "dk", "Danish", "dk", "pc105", NULL, NULL },
{ "dk-latin1", "Danish (latin1)", "dk", "pc105", NULL, NULL },
{ "es", "Spanish", "es", "pc105", NULL, NULL },
{ "et", "Estonian", "ee", "pc105", NULL, NULL },
{ "fi", "Finnish", "fi", "pc105", NULL, NULL },
{ "fi-latin1", "Finnish (latin1)", "fi", "pc105", NULL, NULL },
{ "fr", "French", "fr", "pc105", NULL, NULL },
{ "fr-latin0", "French (latin0)", "fr", "pc105", NULL, NULL },
{ "fr-latin1", "French (latin1)", "fr", "pc105", NULL, NULL },
{ "fr-pc", "French (pc)", "fr", "pc105", NULL, NULL },
{ "fr_CH", "Swiss French", "fr_CH", "pc105", NULL, NULL },
{ "fr_CH-latin1", "Swiss French (latin1)", "fr_CH", "pc105", NULL, NULL },
{ "gr", "Greek", "us,el", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" },
{ "hu", "Hungarian", "hu", "pc105", NULL, NULL },
{ "hu101", "Hungarian (101 key)", "hu", "pc105", NULL, NULL },
{ "is-latin1", "Icelandic", "is", "pc105", NULL, NULL },
{ "it", "Italian", "it", "pc105", NULL, NULL },
{ "it-ibm", "Italian (IBM)", "it", "pc105", NULL, NULL },
{ "it2", "Italian (it2)", "it", "pc105", NULL, NULL },
{ "jp106", "Japanese", "jp", "jp106", NULL, NULL },
{ "la-latin1", "Latin American", "la", "pc105", NULL, NULL },
{ "mk-utf", "Macedonian", "mk,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" },
{ "no", "Norwegian", "no", "pc105", NULL, NULL },
{ "pl", "Polish", "pl", "pc105", NULL, NULL },
{ "pt-latin1", "Portuguese", "pt", "pc105", NULL, NULL },
{ "ro_win", "Romanian", "ro", "pc105", NULL, NULL },
{ "ru", "Russian", "ru,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" },
{ "ru-cp1251", "Russian (cp1251)", "ru,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" },
{ "ru-ms", "Russian (Microsoft)", "ru,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" },
{ "ru1", "Russian (ru1)", "ru,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" },
{ "ru2", "Russian (ru2)", "ru,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" },
{ "ru_win", "Russian (win)", "ru,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" },
{ "speakup", "Speakup", "us", "pc105", NULL, NULL },
{ "speakup-lt", "Speakup (laptop)", "us", "pc105", NULL, NULL },
{ "sv-latin1", "Swedish", "se", "pc105", NULL, NULL },
{ "sg", "Swiss German", "de_CH", "pc105", NULL, NULL },
{ "sg-latin1", "Swiss German (latin1)", "de_CH", "pc105", NULL, NULL },
{ "sk-qwerty", "Slovakian", "sk_qwerty", "pc105", NULL, NULL },
{ "slovene", "Slovenian", "si", "pc105", NULL, NULL },
{ "trq", "Turkish", "tr", "pc105", NULL, NULL },
{ "uk", "United Kingdom", "gb", "pc105", NULL, NULL },
{ "ua", "Ukrainian", "ua,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" },
{ "us-acentos", "U.S. International", "us_intl", "pc105", NULL, NULL },
{ "us", "U.S. English", "us", "pc105", NULL, NULL },
{ NULL, NULL, NULL, NULL, NULL, NULL },
};
/*
* find_keyboard_entry() - scan the __keyboards[] table for the entry that
* corresponds to the specified value; return a pointer to the
* matching entry in the table, if any.
*/
static const KeyboardEntry *find_keyboard_entry(char *value)
{
int i;
if (!value) return NULL;
for (i = 0; __keyboards[i].name; i++) {
if (strcmp(value, __keyboards[i].keytable) == 0) {
return &__keyboards[i];
}
}
return NULL;
} /* find_keyboard_entry() */
/*
* xconfigGeneratePrintPossibleKeyboards() - print the keyboard table
*/
void xconfigGeneratePrintPossibleKeyboards(void)
{
int i;
printf("%-25s%-35s\n\n", "Short Name", "Name");
for (i = 0; __keyboards[i].name; i++) {
printf("%-25s%-35s\n", __keyboards[i].keytable, __keyboards[i].name);
}
printf("\n");
} /* xconfigGeneratePrintPossibleKeyboards() */
/*
* xconfigAddKeyboard() - determine the keyboard type, and then add an
* XConfigInputRec with the appropriate options.
*
* How to detect the keyboard:
*
* - if the user specified on the command line, use that
*
* - if /etc/sysconfig/keyboard exists, and contains a valid
* KEYTABLE entry, use that
*/
int xconfigAddKeyboard(GenerateOptions *gop, XConfigPtr config)
{
char *value, *comment = "default";
const KeyboardEntry *entry = NULL;
XConfigInputPtr input;
/*
* if the user specified on the command line, use that
*/
if (gop->keyboard) {
entry = find_keyboard_entry(gop->keyboard);
if (entry) {
comment = "commandline input";
} else {
xconfigErrorMsg(WarnMsg, "Unable to find keyboard \"%s\".",
gop->keyboard);
}
}
/*
* if /etc/sysconfig/keyboard exists, and contains a valid
* KEYTABLE entry, use that
*/
if (!entry) {
value = find_config_entry("/etc/sysconfig/keyboard", "KEYTABLE=");
entry = find_keyboard_entry(value);
if (value) {
free(value);
}
if (entry) {
comment = "data in \"/etc/sysconfig/keyboard\"";
}
}
/* add a new keyboard input section */
input = xconfigAlloc(sizeof(XConfigInputRec));
input->comment = xconfigStrcat(" # generated from ",
comment, "\n", NULL);
input->identifier = xconfigStrdup("Keyboard0");
/*
* determine which keyboard driver should be used (either "kbd" or
* "keyboard"); if the user specified a keyboard driver use that;
* if 'ROOT/lib/modules/input/kbd_drv.(o|so)' exists, use "kbd";
* otherwise, use "keyboard".
* On Solaris, use the default "keyboard"
*/
if (gop->keyboard_driver) {
input->driver = gop->keyboard_driver;
} else {
#if defined(NV_SUNOS) || defined(NV_BSD)
input->driver = xconfigStrdup("keyboard");
#else
input->driver = xconfigStrdup("kbd");
#endif
}
/*
* set additional keyboard options, based on the Keyboard table
* entry we found above
*/
input->options = NULL;
if (entry) {
if (entry->layout)
xconfigAddNewOption(&input->options, "XkbLayout", entry->layout);
if (entry->model)
xconfigAddNewOption(&input->options, "XkbModel", entry->model);
if (entry->variant)
xconfigAddNewOption(&input->options, "XkbVariant", entry->variant);
if (entry->options)
xconfigAddNewOption(&input->options, "XkbOptions", entry->options);
}
input->next = config->inputs;
config->inputs = input;
return TRUE;
} /* xconfigAddKeyboard() */
/*
* xconfigGetDefaultProjectRoot() - scan some common directories for the X
* project root.
*
* Users of this information should be careful to account for the
* modular layout.
*/
static char *xconfigGetDefaultProjectRoot(void)
{
char *paths[] = { "/usr/X11R6", "/usr/X11", NULL };
struct stat stat_buf;
int i;
for (i = 0; paths[i]; i++) {
if (stat(paths[i], &stat_buf) == -1) {
continue;
}
if (S_ISDIR(stat_buf.st_mode)) {
return paths[i];
}
}
/* default to "/usr/X11R6", I guess */
return paths[0];
} /* xconfigGetDefaultProjectRoot() */
/*
* get_xserver_information() - parse the versionString (from `X
* -version`) and assign relevant information that we infer from the X
* server version.
*/
static int get_xserver_information(const char *versionString,
int *autoloadsGLX,
int *supportsExtensionSection,
int *xineramaPlusCompositeWorks,
const char **compositeExtensionName)
{
#define XSERVER_VERSION_FORMAT_1 "X Window System Version"
#define XSERVER_VERSION_FORMAT_2 "X.Org X Server"
int major, minor, found;
const char *ptr;
/* check if this is an XFree86 X server */
if (strstr(versionString, "XFree86 Version")) {
xconfigErrorMsg(WarnMsg, "XFree86 is not supported.");
return FALSE;
}
/* attempt to parse the major.minor version out of the string */
found = FALSE;
if (((ptr = strstr(versionString, XSERVER_VERSION_FORMAT_1)) != NULL) &&
(sscanf(ptr, XSERVER_VERSION_FORMAT_1 " %d.%d", &major, &minor) == 2)) {
found = TRUE;
}
if (!found &&
((ptr = strstr(versionString, XSERVER_VERSION_FORMAT_2)) != NULL) &&
(sscanf(ptr, XSERVER_VERSION_FORMAT_2 " %d.%d", &major, &minor) == 2)) {
found = TRUE;
}
/* if we can't parse the version, give up */
if (!found) return FALSE;
/*
* supportsExtensionSection: support for the "Extension" xorg.conf
* section was added between X.Org 6.7 and 6.8. To account for
* the X server version wrap, it is easier to check for X servers
* that do not support the Extension section: 6.x (x < 8) X
* servers.
*/
if ((major == 6) && (minor < 8)) {
*supportsExtensionSection = FALSE;
} else {
*supportsExtensionSection = TRUE;
}
/*
* support for autoloading GLX was added in X.Org 1.5. To account
* for the X server version wrap, it is easier to check for X
* servers that do not support GLX autoloading: 6.x, 7.x, or < 1.5
* X servers.
*/
if ((major == 6) || (major == 7) || ((major == 1) && (minor < 5))) {
*autoloadsGLX = FALSE;
} else {
*autoloadsGLX = TRUE;
}
/*
* support for Xinerama and Composite at the same time works on X.Org
* xserver 1.15.
*/
if ((major == 6) || (major == 7) || ((major == 1) && (minor < 15))) {
*xineramaPlusCompositeWorks = FALSE;
} else {
*xineramaPlusCompositeWorks = TRUE;
}
/*
* With X.Org xserver version 1.20, the name of the composite
* extension was changed from "Composite" to "COMPOSITE". As of
* that release extension names are case-sensitive so we must
* ensure the correct case is used.
*/
if (major == 1 && minor >= 20) {
*compositeExtensionName = "COMPOSITE";
} else {
*compositeExtensionName = "Composite";
}
return TRUE;
} /* get_xserver_information() */
/*
* xconfigGetXServerInUse() - try to determine which X server is in use
* (XFree86, Xorg); also determine if the X server supports the
* Extension section of the X config file; support for the "Extension"
* section was added between X.Org 6.7 and 6.8.
*
* Some of the parsing here mimics what is done in the
* check_for_modular_xorg() function in nvidia-installer
*/
#define NV_LINE_LEN 1024
#define EXTRA_PATH "/bin:/usr/bin:/sbin:/usr/sbin:/usr/X11R6/bin:/usr/bin/X11"
#if defined(NV_SUNOS)
#define XSERVER_BIN_NAME "Xorg"
#else
#define XSERVER_BIN_NAME "X"
#endif
void xconfigGetXServerInUse(GenerateOptions *gop)
{
FILE *stream = NULL;
int len, found;
char *cmd, *ptr, *ret;
gop->supports_extension_section = FALSE;
gop->autoloads_glx = FALSE;
gop->xinerama_plus_composite_works = FALSE;
gop->compositeExtensionName = NULL;
/* run `X -version` with a PATH that hopefully includes the X binary */
cmd = xconfigStrcat("PATH=", gop->x_project_root, ":",
EXTRA_PATH, ":$PATH ", XSERVER_BIN_NAME,
" -version 2>&1", NULL);
if ((stream = popen(cmd, "r"))) {
char buf[NV_LINE_LEN];
/* read in as much of the input as we can fit into the buffer */
ptr = buf;
do {
len = NV_LINE_LEN - (ptr - buf) - 1;
ret = fgets(ptr, len, stream);
ptr = strchr(ptr, '\0');
} while ((ret != NULL) && (len > 1));
/*
* process the `X -version` output to infer relevant
* information from this X server
*/
found = get_xserver_information(buf,
&gop->autoloads_glx,
&gop->supports_extension_section,
&gop->xinerama_plus_composite_works,
&gop->compositeExtensionName);
if (!found) {
xconfigErrorMsg(WarnMsg, "Unable to parse X.Org version string.");
}
}
/* Close the popen()'ed stream. */
pclose(stream);
free(cmd);
} /* xconfigGetXServerInUse() */
/*
* xconfigGenerateLoadDefaultOptions - initialize a GenerateOptions
* structure with default values by peeking at the file system.
*/
void xconfigGenerateLoadDefaultOptions(GenerateOptions *gop)
{
memset(gop, 0, sizeof(GenerateOptions));
gop->x_project_root = xconfigGetDefaultProjectRoot();
/* XXX What to default the following to?
gop->keyboard
gop->mouse
gop->keyboard_driver
*/
} /* xconfigGenerateLoadDefaultOptions() */