9838b7032e
This is strictly the application of the script 'x-indent-all.sh' from util/modular. Compared to the patch that Daniel posted in January, I've added a few indent flags: -bap -psl -T PrivatePtr -T pmWait -T _XFUNCPROTOBEGIN -T _XFUNCPROTOEND -T _X_EXPORT The typedefs were needed to make the output of sdksyms.sh match the previous output, otherwise, the code is formatted badly enough that sdksyms.sh generates incorrect output. The generated code was compared with the previous version and found to be essentially identical -- "assert" line numbers and BUILD_TIME were the only differences found. The comparison was done with this script: dir1=$1 dir2=$2 for dir in $dir1 $dir2; do (cd $dir && find . -name '*.o' | while read file; do dir=`dirname $file` base=`basename $file .o` dump=$dir/$base.dump objdump -d $file > $dump done) done find $dir1 -name '*.dump' | while read dump; do otherdump=`echo $dump | sed "s;$dir1;$dir2;"` diff -u $dump $otherdump done Signed-off-by: Keith Packard <keithp@keithp.com> Acked-by: Daniel Stone <daniel@fooishbar.org> Acked-by: Alan Coopersmith <alan.coopersmith@oracle.com>
562 lines
17 KiB
C
562 lines
17 KiB
C
/*
|
|
* Copyright 2002-2003 Red Hat Inc., Durham, North Carolina.
|
|
*
|
|
* 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 on the rights to use, copy, modify, merge,
|
|
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
* and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the
|
|
* next paragraph) shall be included in all copies or substantial
|
|
* portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR 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:
|
|
* Rickard E. (Rik) Faith <faith@redhat.com>
|
|
*
|
|
*/
|
|
|
|
/** \file
|
|
* Provides interface for reading DMX configuration files and for
|
|
* combining that information with command-line configuration parameters. */
|
|
|
|
#ifdef HAVE_DMX_CONFIG_H
|
|
#include <dmx-config.h>
|
|
#endif
|
|
|
|
#include "dmx.h"
|
|
#include "dmxinput.h"
|
|
#include "dmxconfig.h"
|
|
#include "dmxparse.h"
|
|
#include "dmxlog.h"
|
|
#include "dmxcb.h"
|
|
#include "dmxstat.h"
|
|
#include "parser.h"
|
|
|
|
extern int yyparse(void);
|
|
extern FILE *yyin;
|
|
|
|
static char *dmxXkbRules;
|
|
static char *dmxXkbModel;
|
|
static char *dmxXkbLayout;
|
|
static char *dmxXkbVariant;
|
|
static char *dmxXkbOptions;
|
|
|
|
/** Stores lists of configuration information. */
|
|
typedef struct DMXConfigListStruct {
|
|
const char *name;
|
|
struct DMXConfigListStruct *next;
|
|
} DMXConfigList, *DMXConfigListPtr;
|
|
|
|
/** This stucture stores the parsed configuration information. */
|
|
typedef struct DMXConfigCmdStruct {
|
|
const char *filename;
|
|
const char *config;
|
|
DMXConfigList *displays;
|
|
DMXConfigList *inputs;
|
|
DMXConfigList *xinputs;
|
|
} DMXConfigCmd, *DMXConfigCmdPtr;
|
|
|
|
DMXConfigEntryPtr dmxConfigEntry;
|
|
static DMXConfigCmd dmxConfigCmd;
|
|
|
|
static int dmxDisplaysFromCommandLine;
|
|
|
|
/** Make a note that \a display is the name of an X11 display that
|
|
* should be initialized as a backend (output) display. Called from
|
|
* #ddxProcessArgument. */
|
|
void
|
|
dmxConfigStoreDisplay(const char *display)
|
|
{
|
|
DMXConfigListPtr entry = malloc(sizeof(*entry));
|
|
|
|
entry->name = strdup(display);
|
|
entry->next = NULL;
|
|
if (!dmxConfigCmd.displays)
|
|
dmxConfigCmd.displays = entry;
|
|
else {
|
|
DMXConfigList *pt;
|
|
|
|
for (pt = dmxConfigCmd.displays; pt->next; pt = pt->next);
|
|
if (!pt)
|
|
dmxLog(dmxFatal, "dmxConfigStoreDisplay: end of list non-NULL\n");
|
|
pt->next = entry;
|
|
}
|
|
++dmxDisplaysFromCommandLine;
|
|
}
|
|
|
|
/** Make a note that \a input is the name of an X11 display that should
|
|
* be used for input (either a backend or a console input device). */
|
|
void
|
|
dmxConfigStoreInput(const char *input)
|
|
{
|
|
DMXConfigListPtr entry = malloc(sizeof(*entry));
|
|
|
|
entry->name = strdup(input);
|
|
entry->next = NULL;
|
|
if (!dmxConfigCmd.inputs)
|
|
dmxConfigCmd.inputs = entry;
|
|
else {
|
|
DMXConfigList *pt;
|
|
|
|
for (pt = dmxConfigCmd.inputs; pt->next; pt = pt->next);
|
|
if (!pt)
|
|
dmxLog(dmxFatal, "dmxConfigStoreInput: end of list non-NULL\n");
|
|
pt->next = entry;
|
|
}
|
|
}
|
|
|
|
/** Make a note that \a input is the name of an X11 display that should
|
|
* be used for input from XInput extension devices. */
|
|
void
|
|
dmxConfigStoreXInput(const char *input)
|
|
{
|
|
DMXConfigListPtr entry = malloc(sizeof(*entry));
|
|
|
|
entry->name = strdup(input);
|
|
entry->next = NULL;
|
|
if (!dmxConfigCmd.xinputs)
|
|
dmxConfigCmd.xinputs = entry;
|
|
else {
|
|
DMXConfigList *pt;
|
|
|
|
for (pt = dmxConfigCmd.xinputs; pt->next; pt = pt->next);
|
|
if (!pt)
|
|
dmxLog(dmxFatal, "dmxConfigStoreXInput: end of list non-NULL\n");
|
|
pt->next = entry;
|
|
}
|
|
}
|
|
|
|
/** Make a note that \a file is the configuration file. */
|
|
void
|
|
dmxConfigStoreFile(const char *file)
|
|
{
|
|
if (dmxConfigCmd.filename)
|
|
dmxLog(dmxFatal, "Only one -configfile allowed\n");
|
|
dmxConfigCmd.filename = strdup(file);
|
|
}
|
|
|
|
/** Make a note that \a config should be used as the configuration for
|
|
* current instantiation of the DMX server. */
|
|
void
|
|
dmxConfigStoreConfig(const char *config)
|
|
{
|
|
if (dmxConfigCmd.config)
|
|
dmxLog(dmxFatal, "Only one -config allowed\n");
|
|
dmxConfigCmd.config = strdup(config);
|
|
}
|
|
|
|
static int
|
|
dmxConfigReadFile(const char *filename, int debug)
|
|
{
|
|
FILE *str;
|
|
|
|
if (!(str = fopen(filename, "r")))
|
|
return -1;
|
|
dmxLog(dmxInfo, "Reading configuration file \"%s\"\n", filename);
|
|
yyin = str;
|
|
yydebug = debug;
|
|
yyparse();
|
|
fclose(str);
|
|
return 0;
|
|
}
|
|
|
|
static const char *
|
|
dmxConfigMatch(const char *target, DMXConfigEntryPtr entry)
|
|
{
|
|
DMXConfigVirtualPtr v = entry->virtual;
|
|
const char *name = NULL;
|
|
|
|
if (v && v->name)
|
|
name = v->name;
|
|
|
|
if (v && !dmxConfigCmd.config)
|
|
return v->name ? v->name : "<noname>";
|
|
if (!name)
|
|
return NULL;
|
|
if (!strcmp(name, target))
|
|
return name;
|
|
return NULL;
|
|
}
|
|
|
|
static DMXScreenInfo *
|
|
dmxConfigAddDisplay(const char *name,
|
|
int scrnWidth, int scrnHeight,
|
|
int scrnX, int scrnY,
|
|
int scrnXSign, int scrnYSign,
|
|
int rootWidth, int rootHeight,
|
|
int rootX, int rootY, int rootXSign, int rootYSign)
|
|
{
|
|
DMXScreenInfo *dmxScreen;
|
|
|
|
if (!(dmxScreens = realloc(dmxScreens,
|
|
(dmxNumScreens + 1) * sizeof(*dmxScreens))))
|
|
dmxLog(dmxFatal,
|
|
"dmxConfigAddDisplay: realloc failed for screen %d (%s)\n",
|
|
dmxNumScreens, name);
|
|
|
|
dmxScreen = &dmxScreens[dmxNumScreens];
|
|
memset(dmxScreen, 0, sizeof(*dmxScreen));
|
|
dmxScreen->name = name;
|
|
dmxScreen->index = dmxNumScreens;
|
|
dmxScreen->scrnWidth = scrnWidth;
|
|
dmxScreen->scrnHeight = scrnHeight;
|
|
dmxScreen->scrnX = scrnX;
|
|
dmxScreen->scrnY = scrnY;
|
|
dmxScreen->scrnXSign = scrnXSign;
|
|
dmxScreen->scrnYSign = scrnYSign;
|
|
dmxScreen->rootWidth = rootWidth;
|
|
dmxScreen->rootHeight = rootHeight;
|
|
dmxScreen->rootX = rootX;
|
|
dmxScreen->rootY = rootY;
|
|
dmxScreen->stat = dmxStatAlloc();
|
|
++dmxNumScreens;
|
|
return dmxScreen;
|
|
}
|
|
|
|
DMXInputInfo *
|
|
dmxConfigAddInput(const char *name, int core)
|
|
{
|
|
DMXInputInfo *dmxInput;
|
|
|
|
if (!(dmxInputs = realloc(dmxInputs,
|
|
(dmxNumInputs + 1) * sizeof(*dmxInputs))))
|
|
dmxLog(dmxFatal,
|
|
"dmxConfigAddInput: realloc failed for input %d (%s)\n",
|
|
dmxNumInputs, name);
|
|
|
|
dmxInput = &dmxInputs[dmxNumInputs];
|
|
|
|
memset(dmxInput, 0, sizeof(*dmxInput));
|
|
dmxInput->name = name;
|
|
dmxInput->inputIdx = dmxNumInputs;
|
|
dmxInput->scrnIdx = -1;
|
|
dmxInput->core = core;
|
|
++dmxNumInputs;
|
|
return dmxInput;
|
|
}
|
|
|
|
static void
|
|
dmxConfigCopyFromDisplay(DMXConfigDisplayPtr d)
|
|
{
|
|
DMXScreenInfo *dmxScreen;
|
|
|
|
dmxScreen = dmxConfigAddDisplay(d->name,
|
|
d->scrnWidth, d->scrnHeight,
|
|
d->scrnX, d->scrnY,
|
|
d->scrnXSign, d->scrnYSign,
|
|
d->rootWidth, d->rootHeight,
|
|
d->rootX, d->rootY,
|
|
d->rootXSign, d->rootXSign);
|
|
dmxScreen->where = PosAbsolute;
|
|
dmxScreen->whereX = d->rootXOrigin;
|
|
dmxScreen->whereY = d->rootYOrigin;
|
|
}
|
|
|
|
static void
|
|
dmxConfigCopyFromWall(DMXConfigWallPtr w)
|
|
{
|
|
DMXConfigStringPtr pt;
|
|
DMXScreenInfo *dmxScreen;
|
|
int edge = dmxNumScreens;
|
|
int last = dmxNumScreens;
|
|
|
|
if (!w->xwall && !w->ywall) { /* Try to make it square */
|
|
int count;
|
|
|
|
for (pt = w->nameList, count = 0; pt; pt = pt->next)
|
|
++count;
|
|
w->xwall = sqrt(count) + .5;
|
|
}
|
|
|
|
for (pt = w->nameList; pt; pt = pt->next) {
|
|
dmxScreen = dmxConfigAddDisplay(pt->string, w->width, w->height,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
if (pt == w->nameList) { /* Upper left */
|
|
dmxScreen->where = PosAbsolute;
|
|
dmxScreen->whereX = 0;
|
|
dmxScreen->whereY = 0;
|
|
}
|
|
else if (w->xwall) { /* Tile left to right, then top to bottom */
|
|
if (!((dmxNumScreens - 1) % w->xwall)) {
|
|
dmxScreen->where = PosBelow;
|
|
dmxScreen->whereRefScreen = edge;
|
|
edge = dmxNumScreens - 1;
|
|
}
|
|
else {
|
|
dmxScreen->where = PosRightOf;
|
|
dmxScreen->whereRefScreen = last;
|
|
}
|
|
}
|
|
else { /* Tile top to bottom, then left to right */
|
|
if (!((dmxNumScreens - 1) % w->ywall)) {
|
|
dmxScreen->where = PosRightOf;
|
|
dmxScreen->whereRefScreen = edge;
|
|
edge = dmxNumScreens - 1;
|
|
}
|
|
else {
|
|
dmxScreen->where = PosBelow;
|
|
dmxScreen->whereRefScreen = last;
|
|
}
|
|
|
|
}
|
|
last = dmxNumScreens - 1;
|
|
if (dmxScreen->where == PosAbsolute)
|
|
dmxLog(dmxInfo, "Added %s at %d %d\n",
|
|
pt->string, dmxScreen->whereX, dmxScreen->whereY);
|
|
else
|
|
dmxLog(dmxInfo, "Added %s %s %s\n",
|
|
pt->string,
|
|
dmxScreen->where == PosBelow ? "below" : "right of",
|
|
dmxScreens[dmxScreen->whereRefScreen].name);
|
|
}
|
|
}
|
|
|
|
static void
|
|
dmxConfigCopyFromOption(DMXConfigOptionPtr o)
|
|
{
|
|
DMXConfigStringPtr pt;
|
|
int argc = 0;
|
|
char **argv = NULL;
|
|
|
|
if (serverGeneration != 1)
|
|
return; /* FIXME: only do once, for now */
|
|
if (!o || !o->string)
|
|
return;
|
|
for (pt = o->option; pt; pt = pt->next) {
|
|
if (pt->string) {
|
|
++argc;
|
|
argv = realloc(argv, (argc + 1) * sizeof(*argv));
|
|
argv[argc] = (char *) pt->string;
|
|
}
|
|
}
|
|
argv[0] = NULL;
|
|
ProcessCommandLine(argc + 1, argv);
|
|
free(argv);
|
|
}
|
|
|
|
static void
|
|
dmxConfigCopyFromParam(DMXConfigParamPtr p)
|
|
{
|
|
const char **argv;
|
|
int argc;
|
|
|
|
if ((argv = dmxConfigLookupParam(p, "xkbrules", &argc)) && argc == 2) {
|
|
dmxConfigSetXkbRules(argv[1]);
|
|
}
|
|
else if ((argv = dmxConfigLookupParam(p, "xkbmodel", &argc))
|
|
&& argc == 2) {
|
|
dmxConfigSetXkbModel(argv[1]);
|
|
}
|
|
else if ((argv = dmxConfigLookupParam(p, "xkblayout", &argc))
|
|
&& argc == 2) {
|
|
dmxConfigSetXkbLayout(argv[1]);
|
|
}
|
|
else if ((argv = dmxConfigLookupParam(p, "xkbvariant", &argc))
|
|
&& argc == 2) {
|
|
dmxConfigSetXkbVariant(argv[1]);
|
|
}
|
|
else if ((argv = dmxConfigLookupParam(p, "xkboptions", &argc))
|
|
&& argc == 2) {
|
|
dmxConfigSetXkbOptions(argv[1]);
|
|
}
|
|
}
|
|
|
|
static void
|
|
dmxConfigCopyData(DMXConfigVirtualPtr v)
|
|
{
|
|
DMXConfigSubPtr sub;
|
|
|
|
if (v->dim)
|
|
dmxSetWidthHeight(v->dim->x, v->dim->y);
|
|
else
|
|
dmxSetWidthHeight(0, 0);
|
|
for (sub = v->subentry; sub; sub = sub->next) {
|
|
switch (sub->type) {
|
|
case dmxConfigDisplay:
|
|
dmxConfigCopyFromDisplay(sub->display);
|
|
break;
|
|
case dmxConfigWall:
|
|
dmxConfigCopyFromWall(sub->wall);
|
|
break;
|
|
case dmxConfigOption:
|
|
dmxConfigCopyFromOption(sub->option);
|
|
break;
|
|
case dmxConfigParam:
|
|
dmxConfigCopyFromParam(sub->param);
|
|
break;
|
|
default:
|
|
dmxLog(dmxFatal,
|
|
"dmxConfigCopyData: not a display, wall, or value\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
dmxConfigFromCommandLine(void)
|
|
{
|
|
DMXConfigListPtr pt;
|
|
|
|
dmxLog(dmxInfo, "Using configuration from command line\n");
|
|
for (pt = dmxConfigCmd.displays; pt; pt = pt->next) {
|
|
DMXScreenInfo *dmxScreen = dmxConfigAddDisplay(pt->name,
|
|
0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0);
|
|
|
|
if (dmxNumScreens == 1) {
|
|
dmxScreen->where = PosAbsolute;
|
|
dmxScreen->whereX = 0;
|
|
dmxScreen->whereY = 0;
|
|
dmxLog(dmxInfo, "Added %s at %d %d\n",
|
|
dmxScreen->name, dmxScreen->whereX, dmxScreen->whereY);
|
|
}
|
|
else {
|
|
dmxScreen->where = PosRightOf;
|
|
dmxScreen->whereRefScreen = dmxNumScreens - 2;
|
|
if (dmxScreen->whereRefScreen < 0)
|
|
dmxScreen->whereRefScreen = 0;
|
|
dmxLog(dmxInfo, "Added %s %s %s\n",
|
|
dmxScreen->name,
|
|
dmxScreen->where == PosBelow ? "below" : "right of",
|
|
dmxScreens[dmxScreen->whereRefScreen].name);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
dmxConfigFromConfigFile(void)
|
|
{
|
|
DMXConfigEntryPtr pt;
|
|
const char *name;
|
|
|
|
for (pt = dmxConfigEntry; pt; pt = pt->next) {
|
|
/* FIXME -- if an input is specified, use it */
|
|
if (pt->type != dmxConfigVirtual)
|
|
continue;
|
|
if ((name = dmxConfigMatch(dmxConfigCmd.config, pt))) {
|
|
dmxLog(dmxInfo, "Using configuration \"%s\"\n", name);
|
|
dmxConfigCopyData(pt->virtual);
|
|
return;
|
|
}
|
|
}
|
|
dmxLog(dmxFatal, "Could not find configuration \"%s\" in \"%s\"\n",
|
|
dmxConfigCmd.config, dmxConfigCmd.filename);
|
|
}
|
|
|
|
static void
|
|
dmxConfigConfigInputs(void)
|
|
{
|
|
DMXConfigListPtr pt;
|
|
|
|
if (dmxNumInputs)
|
|
return;
|
|
|
|
if (dmxConfigCmd.inputs) { /* Use command line */
|
|
for (pt = dmxConfigCmd.inputs; pt; pt = pt->next)
|
|
dmxConfigAddInput(pt->name, TRUE);
|
|
}
|
|
else if (dmxNumScreens) { /* Use first display */
|
|
dmxConfigAddInput(dmxScreens[0].name, TRUE);
|
|
}
|
|
else { /* Use dummy */
|
|
dmxConfigAddInput("dummy", TRUE);
|
|
}
|
|
|
|
if (dmxConfigCmd.xinputs) { /* Non-core devices from command line */
|
|
for (pt = dmxConfigCmd.xinputs; pt; pt = pt->next)
|
|
dmxConfigAddInput(pt->name, FALSE);
|
|
}
|
|
}
|
|
|
|
/** Set up the appropriate global variables so that the DMX server will
|
|
* be initialized using the configuration specified in the config file
|
|
* and on the command line. */
|
|
void
|
|
dmxConfigConfigure(void)
|
|
{
|
|
if (dmxConfigEntry) {
|
|
dmxConfigFreeEntry(dmxConfigEntry);
|
|
dmxConfigEntry = NULL;
|
|
}
|
|
if (dmxConfigCmd.filename) {
|
|
if (dmxConfigCmd.displays)
|
|
dmxLog(dmxWarning,
|
|
"Using configuration file \"%s\" instead of command line\n",
|
|
dmxConfigCmd.filename);
|
|
dmxConfigReadFile(dmxConfigCmd.filename, 0);
|
|
dmxConfigFromConfigFile();
|
|
}
|
|
else {
|
|
if (dmxConfigCmd.config)
|
|
dmxLog(dmxWarning,
|
|
"Configuration name (%s) without configuration file\n",
|
|
dmxConfigCmd.config);
|
|
dmxConfigFromCommandLine();
|
|
}
|
|
dmxConfigConfigInputs();
|
|
}
|
|
|
|
/** This function determines the number of displays we WILL have and
|
|
* sets MAXSCREENS to that value. This is difficult since the number
|
|
* depends on the command line (which is easy to count) or on the config
|
|
* file, which has to be parsed. */
|
|
void
|
|
dmxConfigSetMaxScreens(void)
|
|
{
|
|
static int processing = 0;
|
|
|
|
if (processing)
|
|
return; /* Prevent reentry via ProcessCommandLine */
|
|
processing = 1;
|
|
if (dmxConfigCmd.filename) {
|
|
if (!dmxNumScreens)
|
|
dmxConfigConfigure();
|
|
#ifndef MAXSCREENS
|
|
SetMaxScreens(dmxNumScreens);
|
|
#endif
|
|
}
|
|
else
|
|
#ifndef MAXSCREENS
|
|
SetMaxScreens(dmxDisplaysFromCommandLine);
|
|
#endif
|
|
processing = 0;
|
|
}
|
|
|
|
/** This macro is used to generate the following access methods:
|
|
* - dmxConfig{Set,Get}rules
|
|
* - dmxConfig{Set,Get}model
|
|
* - dmxConfig{Set,Get}layout
|
|
* - dmxConfig{Set,Get}variant
|
|
* - dmxConfig{Set,Get}options
|
|
* These methods are used to read and write information about the keyboard. */
|
|
|
|
#define GEN(param,glob,def) \
|
|
void dmxConfigSet##glob(const char *param) { \
|
|
if (dmx##glob) free((void *)dmx##glob); \
|
|
dmx##glob = strdup(param); \
|
|
} \
|
|
char *dmxConfigGet##glob(void) { \
|
|
return (char *)(dmx##glob ? dmx##glob : def); \
|
|
}
|
|
|
|
GEN(rules, XkbRules, XKB_DFLT_RULES)
|
|
GEN(model, XkbModel, XKB_DFLT_MODEL)
|
|
GEN(layout, XkbLayout, XKB_DFLT_LAYOUT)
|
|
GEN(variant, XkbVariant, XKB_DFLT_VARIANT)
|
|
GEN(options, XkbOptions, XKB_DFLT_OPTIONS)
|