1706f2543Smrg/* 2706f2543Smrg * Copyright 2002-2003 Red Hat Inc., Durham, North Carolina. 3706f2543Smrg * 4706f2543Smrg * All Rights Reserved. 5706f2543Smrg * 6706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining 7706f2543Smrg * a copy of this software and associated documentation files (the 8706f2543Smrg * "Software"), to deal in the Software without restriction, including 9706f2543Smrg * without limitation on the rights to use, copy, modify, merge, 10706f2543Smrg * publish, distribute, sublicense, and/or sell copies of the Software, 11706f2543Smrg * and to permit persons to whom the Software is furnished to do so, 12706f2543Smrg * subject to the following conditions: 13706f2543Smrg * 14706f2543Smrg * The above copyright notice and this permission notice (including the 15706f2543Smrg * next paragraph) shall be included in all copies or substantial 16706f2543Smrg * portions of the Software. 17706f2543Smrg * 18706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19706f2543Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20706f2543Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21706f2543Smrg * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS 22706f2543Smrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 23706f2543Smrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24706f2543Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25706f2543Smrg * SOFTWARE. 26706f2543Smrg */ 27706f2543Smrg 28706f2543Smrg/* 29706f2543Smrg * Authors: 30706f2543Smrg * Rickard E. (Rik) Faith <faith@redhat.com> 31706f2543Smrg * 32706f2543Smrg */ 33706f2543Smrg 34706f2543Smrg/** \file 35706f2543Smrg * Provides interface for reading DMX configuration files and for 36706f2543Smrg * combining that information with command-line configuration parameters. */ 37706f2543Smrg 38706f2543Smrg 39706f2543Smrg#ifdef HAVE_DMX_CONFIG_H 40706f2543Smrg#include <dmx-config.h> 41706f2543Smrg#endif 42706f2543Smrg 43706f2543Smrg#include "dmx.h" 44706f2543Smrg#include "dmxinput.h" 45706f2543Smrg#include "dmxconfig.h" 46706f2543Smrg#include "dmxparse.h" 47706f2543Smrg#include "dmxlog.h" 48706f2543Smrg#include "dmxcb.h" 49706f2543Smrg#include "dmxstat.h" 50706f2543Smrg#include "parser.h" 51706f2543Smrg 52706f2543Smrgextern int yyparse(void); 53706f2543Smrgextern FILE *yyin; 54706f2543Smrg 55706f2543Smrgstatic char *dmxXkbRules; 56706f2543Smrgstatic char *dmxXkbModel; 57706f2543Smrgstatic char *dmxXkbLayout; 58706f2543Smrgstatic char *dmxXkbVariant; 59706f2543Smrgstatic char *dmxXkbOptions; 60706f2543Smrg 61706f2543Smrg/** Stores lists of configuration information. */ 62706f2543Smrgtypedef struct DMXConfigListStruct { 63706f2543Smrg const char *name; 64706f2543Smrg struct DMXConfigListStruct *next; 65706f2543Smrg} DMXConfigList, *DMXConfigListPtr; 66706f2543Smrg 67706f2543Smrg/** This stucture stores the parsed configuration information. */ 68706f2543Smrgtypedef struct DMXConfigCmdStruct { 69706f2543Smrg const char *filename; 70706f2543Smrg const char *config; 71706f2543Smrg DMXConfigList *displays; 72706f2543Smrg DMXConfigList *inputs; 73706f2543Smrg DMXConfigList *xinputs; 74706f2543Smrg} DMXConfigCmd, *DMXConfigCmdPtr; 75706f2543Smrg 76706f2543SmrgDMXConfigEntryPtr dmxConfigEntry; 77706f2543Smrgstatic DMXConfigCmd dmxConfigCmd; 78706f2543Smrg 79706f2543Smrgstatic int dmxDisplaysFromCommandLine; 80706f2543Smrg 81706f2543Smrg/** Make a note that \a display is the name of an X11 display that 82706f2543Smrg * should be initialized as a backend (output) display. Called from 83706f2543Smrg * #ddxProcessArgument. */ 84706f2543Smrgvoid dmxConfigStoreDisplay(const char *display) 85706f2543Smrg{ 86706f2543Smrg DMXConfigListPtr entry = malloc(sizeof(*entry)); 87706f2543Smrg entry->name = strdup(display); 88706f2543Smrg entry->next = NULL; 89706f2543Smrg if (!dmxConfigCmd.displays) dmxConfigCmd.displays = entry; 90706f2543Smrg else { 91706f2543Smrg DMXConfigList *pt; 92706f2543Smrg for (pt = dmxConfigCmd.displays; pt->next; pt = pt->next); 93706f2543Smrg if (!pt) 94706f2543Smrg dmxLog(dmxFatal, "dmxConfigStoreDisplay: end of list non-NULL\n"); 95706f2543Smrg pt->next = entry; 96706f2543Smrg } 97706f2543Smrg ++dmxDisplaysFromCommandLine; 98706f2543Smrg} 99706f2543Smrg 100706f2543Smrg/** Make a note that \a input is the name of an X11 display that should 101706f2543Smrg * be used for input (either a backend or a console input device). */ 102706f2543Smrgvoid dmxConfigStoreInput(const char *input) 103706f2543Smrg{ 104706f2543Smrg DMXConfigListPtr entry = malloc(sizeof(*entry)); 105706f2543Smrg entry->name = strdup(input); 106706f2543Smrg entry->next = NULL; 107706f2543Smrg if (!dmxConfigCmd.inputs) dmxConfigCmd.inputs = entry; 108706f2543Smrg else { 109706f2543Smrg DMXConfigList *pt; 110706f2543Smrg for (pt = dmxConfigCmd.inputs; pt->next; pt = pt->next); 111706f2543Smrg if (!pt) 112706f2543Smrg dmxLog(dmxFatal, "dmxConfigStoreInput: end of list non-NULL\n"); 113706f2543Smrg pt->next = entry; 114706f2543Smrg } 115706f2543Smrg} 116706f2543Smrg 117706f2543Smrg/** Make a note that \a input is the name of an X11 display that should 118706f2543Smrg * be used for input from XInput extension devices. */ 119706f2543Smrgvoid dmxConfigStoreXInput(const char *input) 120706f2543Smrg{ 121706f2543Smrg DMXConfigListPtr entry = malloc(sizeof(*entry)); 122706f2543Smrg entry->name = strdup(input); 123706f2543Smrg entry->next = NULL; 124706f2543Smrg if (!dmxConfigCmd.xinputs) dmxConfigCmd.xinputs = entry; 125706f2543Smrg else { 126706f2543Smrg DMXConfigList *pt; 127706f2543Smrg for (pt = dmxConfigCmd.xinputs; pt->next; pt = pt->next); 128706f2543Smrg if (!pt) 129706f2543Smrg dmxLog(dmxFatal, "dmxConfigStoreXInput: end of list non-NULL\n"); 130706f2543Smrg pt->next = entry; 131706f2543Smrg } 132706f2543Smrg} 133706f2543Smrg 134706f2543Smrg/** Make a note that \a file is the configuration file. */ 135706f2543Smrgvoid dmxConfigStoreFile(const char *file) 136706f2543Smrg{ 137706f2543Smrg if (dmxConfigCmd.filename) 138706f2543Smrg dmxLog(dmxFatal, "Only one -configfile allowed\n"); 139706f2543Smrg dmxConfigCmd.filename = strdup(file); 140706f2543Smrg} 141706f2543Smrg 142706f2543Smrg/** Make a note that \a config should be used as the configuration for 143706f2543Smrg * current instantiation of the DMX server. */ 144706f2543Smrgvoid dmxConfigStoreConfig(const char *config) 145706f2543Smrg{ 146706f2543Smrg if (dmxConfigCmd.config) dmxLog(dmxFatal, "Only one -config allowed\n"); 147706f2543Smrg dmxConfigCmd.config = strdup(config); 148706f2543Smrg} 149706f2543Smrg 150706f2543Smrgstatic int dmxConfigReadFile(const char *filename, int debug) 151706f2543Smrg{ 152706f2543Smrg FILE *str; 153706f2543Smrg 154706f2543Smrg if (!(str = fopen(filename, "r"))) return -1; 155706f2543Smrg dmxLog(dmxInfo, "Reading configuration file \"%s\"\n", filename); 156706f2543Smrg yyin = str; 157706f2543Smrg yydebug = debug; 158706f2543Smrg yyparse(); 159706f2543Smrg fclose(str); 160706f2543Smrg return 0; 161706f2543Smrg} 162706f2543Smrg 163706f2543Smrgstatic const char *dmxConfigMatch(const char *target, DMXConfigEntryPtr entry) 164706f2543Smrg{ 165706f2543Smrg DMXConfigVirtualPtr v = entry->virtual; 166706f2543Smrg const char *name = NULL; 167706f2543Smrg 168706f2543Smrg if (v && v->name) name = v->name; 169706f2543Smrg 170706f2543Smrg if (v && !dmxConfigCmd.config) return v->name ? v->name : "<noname>"; 171706f2543Smrg if (!name) return NULL; 172706f2543Smrg if (!strcmp(name, target)) return name; 173706f2543Smrg return NULL; 174706f2543Smrg} 175706f2543Smrg 176706f2543Smrgstatic DMXScreenInfo *dmxConfigAddDisplay(const char *name, 177706f2543Smrg int scrnWidth, int scrnHeight, 178706f2543Smrg int scrnX, int scrnY, 179706f2543Smrg int scrnXSign, int scrnYSign, 180706f2543Smrg int rootWidth, int rootHeight, 181706f2543Smrg int rootX, int rootY, 182706f2543Smrg int rootXSign, int rootYSign) 183706f2543Smrg{ 184706f2543Smrg DMXScreenInfo *dmxScreen; 185706f2543Smrg 186706f2543Smrg if (!(dmxScreens = realloc(dmxScreens, 187706f2543Smrg (dmxNumScreens+1) * sizeof(*dmxScreens)))) 188706f2543Smrg dmxLog(dmxFatal, 189706f2543Smrg "dmxConfigAddDisplay: realloc failed for screen %d (%s)\n", 190706f2543Smrg dmxNumScreens, name); 191706f2543Smrg 192706f2543Smrg dmxScreen = &dmxScreens[dmxNumScreens]; 193706f2543Smrg memset(dmxScreen, 0, sizeof(*dmxScreen)); 194706f2543Smrg dmxScreen->name = name; 195706f2543Smrg dmxScreen->index = dmxNumScreens; 196706f2543Smrg dmxScreen->scrnWidth = scrnWidth; 197706f2543Smrg dmxScreen->scrnHeight = scrnHeight; 198706f2543Smrg dmxScreen->scrnX = scrnX; 199706f2543Smrg dmxScreen->scrnY = scrnY; 200706f2543Smrg dmxScreen->scrnXSign = scrnXSign; 201706f2543Smrg dmxScreen->scrnYSign = scrnYSign; 202706f2543Smrg dmxScreen->rootWidth = rootWidth; 203706f2543Smrg dmxScreen->rootHeight = rootHeight; 204706f2543Smrg dmxScreen->rootX = rootX; 205706f2543Smrg dmxScreen->rootY = rootY; 206706f2543Smrg dmxScreen->stat = dmxStatAlloc(); 207706f2543Smrg ++dmxNumScreens; 208706f2543Smrg return dmxScreen; 209706f2543Smrg} 210706f2543Smrg 211706f2543SmrgDMXInputInfo *dmxConfigAddInput(const char *name, int core) 212706f2543Smrg{ 213706f2543Smrg DMXInputInfo *dmxInput; 214706f2543Smrg 215706f2543Smrg if (!(dmxInputs = realloc(dmxInputs, 216706f2543Smrg (dmxNumInputs+1) * sizeof(*dmxInputs)))) 217706f2543Smrg dmxLog(dmxFatal, 218706f2543Smrg "dmxConfigAddInput: realloc failed for input %d (%s)\n", 219706f2543Smrg dmxNumInputs, name); 220706f2543Smrg 221706f2543Smrg dmxInput = &dmxInputs[dmxNumInputs]; 222706f2543Smrg 223706f2543Smrg memset(dmxInput, 0, sizeof(*dmxInput)); 224706f2543Smrg dmxInput->name = name; 225706f2543Smrg dmxInput->inputIdx = dmxNumInputs; 226706f2543Smrg dmxInput->scrnIdx = -1; 227706f2543Smrg dmxInput->core = core; 228706f2543Smrg ++dmxNumInputs; 229706f2543Smrg return dmxInput; 230706f2543Smrg} 231706f2543Smrg 232706f2543Smrgstatic void dmxConfigCopyFromDisplay(DMXConfigDisplayPtr d) 233706f2543Smrg{ 234706f2543Smrg DMXScreenInfo *dmxScreen; 235706f2543Smrg 236706f2543Smrg dmxScreen = dmxConfigAddDisplay(d->name, 237706f2543Smrg d->scrnWidth, d->scrnHeight, 238706f2543Smrg d->scrnX, d->scrnY, 239706f2543Smrg d->scrnXSign, d->scrnYSign, 240706f2543Smrg d->rootWidth, d->rootHeight, 241706f2543Smrg d->rootX, d->rootY, 242706f2543Smrg d->rootXSign, d->rootXSign); 243706f2543Smrg dmxScreen->where = PosAbsolute; 244706f2543Smrg dmxScreen->whereX = d->rootXOrigin; 245706f2543Smrg dmxScreen->whereY = d->rootYOrigin; 246706f2543Smrg} 247706f2543Smrg 248706f2543Smrgstatic void dmxConfigCopyFromWall(DMXConfigWallPtr w) 249706f2543Smrg{ 250706f2543Smrg DMXConfigStringPtr pt; 251706f2543Smrg DMXScreenInfo *dmxScreen; 252706f2543Smrg int edge = dmxNumScreens; 253706f2543Smrg int last = dmxNumScreens; 254706f2543Smrg 255706f2543Smrg if (!w->xwall && !w->ywall) { /* Try to make it square */ 256706f2543Smrg int count; 257706f2543Smrg for (pt = w->nameList, count = 0; pt; pt = pt->next) ++count; 258706f2543Smrg w->xwall = sqrt(count) + .5; 259706f2543Smrg } 260706f2543Smrg 261706f2543Smrg for (pt = w->nameList; pt; pt = pt->next) { 262706f2543Smrg dmxScreen = dmxConfigAddDisplay(pt->string, w->width, w->height, 263706f2543Smrg 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 264706f2543Smrg if (pt == w->nameList) { /* Upper left */ 265706f2543Smrg dmxScreen->where = PosAbsolute; 266706f2543Smrg dmxScreen->whereX = 0; 267706f2543Smrg dmxScreen->whereY = 0; 268706f2543Smrg } else if (w->xwall) { /* Tile left to right, then top to bottom */ 269706f2543Smrg if (!((dmxNumScreens-1) % w->xwall)) { 270706f2543Smrg dmxScreen->where = PosBelow; 271706f2543Smrg dmxScreen->whereRefScreen = edge; 272706f2543Smrg edge = dmxNumScreens-1; 273706f2543Smrg } else { 274706f2543Smrg dmxScreen->where = PosRightOf; 275706f2543Smrg dmxScreen->whereRefScreen = last; 276706f2543Smrg } 277706f2543Smrg } else { /* Tile top to bottom, then left to right */ 278706f2543Smrg if (!((dmxNumScreens-1) % w->ywall)) { 279706f2543Smrg dmxScreen->where = PosRightOf; 280706f2543Smrg dmxScreen->whereRefScreen = edge; 281706f2543Smrg edge = dmxNumScreens-1; 282706f2543Smrg } else { 283706f2543Smrg dmxScreen->where = PosBelow; 284706f2543Smrg dmxScreen->whereRefScreen = last; 285706f2543Smrg } 286706f2543Smrg 287706f2543Smrg } 288706f2543Smrg last = dmxNumScreens-1; 289706f2543Smrg if (dmxScreen->where == PosAbsolute) 290706f2543Smrg dmxLog(dmxInfo, "Added %s at %d %d\n", 291706f2543Smrg pt->string, dmxScreen->whereX, dmxScreen->whereY); 292706f2543Smrg else 293706f2543Smrg dmxLog(dmxInfo, "Added %s %s %s\n", 294706f2543Smrg pt->string, 295706f2543Smrg dmxScreen->where == PosBelow ? "below" : "right of", 296706f2543Smrg dmxScreens[dmxScreen->whereRefScreen].name); 297706f2543Smrg } 298706f2543Smrg} 299706f2543Smrg 300706f2543Smrgstatic void dmxConfigCopyFromOption(DMXConfigOptionPtr o) 301706f2543Smrg{ 302706f2543Smrg DMXConfigStringPtr pt; 303706f2543Smrg int argc = 0; 304706f2543Smrg char **argv = NULL; 305706f2543Smrg 306706f2543Smrg if (serverGeneration != 1) return; /* FIXME: only do once, for now */ 307706f2543Smrg if (!o || !o->string) return; 308706f2543Smrg for (pt = o->option; pt; pt = pt->next) { 309706f2543Smrg if (pt->string) { 310706f2543Smrg ++argc; 311706f2543Smrg argv = realloc(argv, (argc+1) * sizeof(*argv)); 312706f2543Smrg argv[argc] = (char *)pt->string; 313706f2543Smrg } 314706f2543Smrg } 315706f2543Smrg argv[0] = NULL; 316706f2543Smrg ProcessCommandLine(argc+1, argv); 317706f2543Smrg free(argv); 318706f2543Smrg} 319706f2543Smrg 320706f2543Smrgstatic void dmxConfigCopyFromParam(DMXConfigParamPtr p) 321706f2543Smrg{ 322706f2543Smrg const char **argv; 323706f2543Smrg int argc; 324706f2543Smrg 325706f2543Smrg if ((argv = dmxConfigLookupParam(p, "xkbrules", &argc)) && argc == 2) { 326706f2543Smrg dmxConfigSetXkbRules(argv[1]); 327706f2543Smrg } else if ((argv = dmxConfigLookupParam(p, "xkbmodel", &argc)) 328706f2543Smrg && argc == 2) { 329706f2543Smrg dmxConfigSetXkbModel(argv[1]); 330706f2543Smrg } else if ((argv = dmxConfigLookupParam(p, "xkblayout", &argc)) 331706f2543Smrg && argc == 2) { 332706f2543Smrg dmxConfigSetXkbLayout(argv[1]); 333706f2543Smrg } else if ((argv = dmxConfigLookupParam(p, "xkbvariant", &argc)) 334706f2543Smrg && argc == 2) { 335706f2543Smrg dmxConfigSetXkbVariant(argv[1]); 336706f2543Smrg } else if ((argv = dmxConfigLookupParam(p, "xkboptions", &argc)) 337706f2543Smrg && argc == 2) { 338706f2543Smrg dmxConfigSetXkbOptions(argv[1]); 339706f2543Smrg } 340706f2543Smrg} 341706f2543Smrg 342706f2543Smrgstatic void dmxConfigCopyData(DMXConfigVirtualPtr v) 343706f2543Smrg{ 344706f2543Smrg DMXConfigSubPtr sub; 345706f2543Smrg 346706f2543Smrg if (v->dim) dmxSetWidthHeight(v->dim->x, v->dim->y); 347706f2543Smrg else dmxSetWidthHeight(0, 0); 348706f2543Smrg for (sub = v->subentry; sub; sub = sub->next) { 349706f2543Smrg switch (sub->type) { 350706f2543Smrg case dmxConfigDisplay: dmxConfigCopyFromDisplay(sub->display); break; 351706f2543Smrg case dmxConfigWall: dmxConfigCopyFromWall(sub->wall); break; 352706f2543Smrg case dmxConfigOption: dmxConfigCopyFromOption(sub->option); break; 353706f2543Smrg case dmxConfigParam: dmxConfigCopyFromParam(sub->param); break; 354706f2543Smrg default: 355706f2543Smrg dmxLog(dmxFatal, 356706f2543Smrg "dmxConfigCopyData: not a display, wall, or value\n"); 357706f2543Smrg } 358706f2543Smrg } 359706f2543Smrg} 360706f2543Smrg 361706f2543Smrgstatic void dmxConfigFromCommandLine(void) 362706f2543Smrg{ 363706f2543Smrg DMXConfigListPtr pt; 364706f2543Smrg 365706f2543Smrg dmxLog(dmxInfo, "Using configuration from command line\n"); 366706f2543Smrg for (pt = dmxConfigCmd.displays; pt; pt = pt->next) { 367706f2543Smrg DMXScreenInfo *dmxScreen = dmxConfigAddDisplay(pt->name, 368706f2543Smrg 0, 0, 0, 0, 0, 0, 369706f2543Smrg 0, 0, 0, 0, 0, 0); 370706f2543Smrg if (dmxNumScreens == 1) { 371706f2543Smrg dmxScreen->where = PosAbsolute; 372706f2543Smrg dmxScreen->whereX = 0; 373706f2543Smrg dmxScreen->whereY = 0; 374706f2543Smrg dmxLog(dmxInfo, "Added %s at %d %d\n", 375706f2543Smrg dmxScreen->name, dmxScreen->whereX, dmxScreen->whereY); 376706f2543Smrg } else { 377706f2543Smrg dmxScreen->where = PosRightOf; 378706f2543Smrg dmxScreen->whereRefScreen = dmxNumScreens - 2; 379706f2543Smrg if (dmxScreen->whereRefScreen < 0) dmxScreen->whereRefScreen = 0; 380706f2543Smrg dmxLog(dmxInfo, "Added %s %s %s\n", 381706f2543Smrg dmxScreen->name, 382706f2543Smrg dmxScreen->where == PosBelow ? "below" : "right of", 383706f2543Smrg dmxScreens[dmxScreen->whereRefScreen].name); 384706f2543Smrg } 385706f2543Smrg } 386706f2543Smrg} 387706f2543Smrg 388706f2543Smrgstatic void dmxConfigFromConfigFile(void) 389706f2543Smrg{ 390706f2543Smrg DMXConfigEntryPtr pt; 391706f2543Smrg const char *name; 392706f2543Smrg 393706f2543Smrg for (pt = dmxConfigEntry; pt; pt = pt->next) { 394706f2543Smrg /* FIXME -- if an input is specified, use it */ 395706f2543Smrg if (pt->type != dmxConfigVirtual) continue; 396706f2543Smrg if ((name = dmxConfigMatch(dmxConfigCmd.config, pt))) { 397706f2543Smrg dmxLog(dmxInfo, "Using configuration \"%s\"\n", name); 398706f2543Smrg dmxConfigCopyData(pt->virtual); 399706f2543Smrg return; 400706f2543Smrg } 401706f2543Smrg } 402706f2543Smrg dmxLog(dmxFatal, "Could not find configuration \"%s\" in \"%s\"\n", 403706f2543Smrg dmxConfigCmd.config, dmxConfigCmd.filename); 404706f2543Smrg} 405706f2543Smrg 406706f2543Smrgstatic void dmxConfigConfigInputs(void) 407706f2543Smrg{ 408706f2543Smrg DMXConfigListPtr pt; 409706f2543Smrg 410706f2543Smrg if (dmxNumInputs) return; 411706f2543Smrg 412706f2543Smrg if (dmxConfigCmd.inputs) { /* Use command line */ 413706f2543Smrg for (pt = dmxConfigCmd.inputs; pt; pt = pt->next) 414706f2543Smrg dmxConfigAddInput(pt->name, TRUE); 415706f2543Smrg } else if (dmxNumScreens) { /* Use first display */ 416706f2543Smrg dmxConfigAddInput(dmxScreens[0].name, TRUE); 417706f2543Smrg } else { /* Use dummy */ 418706f2543Smrg dmxConfigAddInput("dummy", TRUE); 419706f2543Smrg } 420706f2543Smrg 421706f2543Smrg if (dmxConfigCmd.xinputs) { /* Non-core devices from command line */ 422706f2543Smrg for (pt = dmxConfigCmd.xinputs; pt; pt = pt->next) 423706f2543Smrg dmxConfigAddInput(pt->name, FALSE); 424706f2543Smrg } 425706f2543Smrg} 426706f2543Smrg 427706f2543Smrg/** Set up the appropriate global variables so that the DMX server will 428706f2543Smrg * be initialized using the configuration specified in the config file 429706f2543Smrg * and on the command line. */ 430706f2543Smrgvoid dmxConfigConfigure(void) 431706f2543Smrg{ 432706f2543Smrg if (dmxConfigEntry) { 433706f2543Smrg dmxConfigFreeEntry(dmxConfigEntry); 434706f2543Smrg dmxConfigEntry = NULL; 435706f2543Smrg } 436706f2543Smrg if (dmxConfigCmd.filename) { 437706f2543Smrg if (dmxConfigCmd.displays) 438706f2543Smrg dmxLog(dmxWarning, 439706f2543Smrg "Using configuration file \"%s\" instead of command line\n", 440706f2543Smrg dmxConfigCmd.filename); 441706f2543Smrg dmxConfigReadFile(dmxConfigCmd.filename, 0); 442706f2543Smrg dmxConfigFromConfigFile(); 443706f2543Smrg } else { 444706f2543Smrg if (dmxConfigCmd.config) 445706f2543Smrg dmxLog(dmxWarning, 446706f2543Smrg "Configuration name (%s) without configuration file\n", 447706f2543Smrg dmxConfigCmd.config); 448706f2543Smrg dmxConfigFromCommandLine(); 449706f2543Smrg } 450706f2543Smrg dmxConfigConfigInputs(); 451706f2543Smrg} 452706f2543Smrg 453706f2543Smrg/** This function determines the number of displays we WILL have and 454706f2543Smrg * sets MAXSCREENS to that value. This is difficult since the number 455706f2543Smrg * depends on the command line (which is easy to count) or on the config 456706f2543Smrg * file, which has to be parsed. */ 457706f2543Smrgvoid dmxConfigSetMaxScreens(void) 458706f2543Smrg{ 459706f2543Smrg static int processing = 0; 460706f2543Smrg 461706f2543Smrg if (processing) return; /* Prevent reentry via ProcessCommandLine */ 462706f2543Smrg processing = 1; 463706f2543Smrg if (dmxConfigCmd.filename) { 464706f2543Smrg if (!dmxNumScreens) 465706f2543Smrg dmxConfigConfigure(); 466706f2543Smrg#ifndef MAXSCREENS 467706f2543Smrg SetMaxScreens(dmxNumScreens); 468706f2543Smrg#endif 469706f2543Smrg } else 470706f2543Smrg#ifndef MAXSCREENS 471706f2543Smrg SetMaxScreens(dmxDisplaysFromCommandLine); 472706f2543Smrg#endif 473706f2543Smrg processing = 0; 474706f2543Smrg} 475706f2543Smrg 476706f2543Smrg/** This macro is used to generate the following access methods: 477706f2543Smrg * - dmxConfig{Set,Get}rules 478706f2543Smrg * - dmxConfig{Set,Get}model 479706f2543Smrg * - dmxConfig{Set,Get}layout 480706f2543Smrg * - dmxConfig{Set,Get}variant 481706f2543Smrg * - dmxConfig{Set,Get}options 482706f2543Smrg * These methods are used to read and write information about the keyboard. */ 483706f2543Smrg 484706f2543Smrg#define GEN(param,glob,def) \ 485706f2543Smrg void dmxConfigSet##glob(const char *param) { \ 486706f2543Smrg if (dmx##glob) free((void *)dmx##glob); \ 487706f2543Smrg dmx##glob = strdup(param); \ 488706f2543Smrg } \ 489706f2543Smrg char *dmxConfigGet##glob(void) { \ 490706f2543Smrg return (char *)(dmx##glob ? dmx##glob : def); \ 491706f2543Smrg } 492706f2543Smrg 493706f2543SmrgGEN(rules, XkbRules, XKB_DFLT_RULES) 494706f2543SmrgGEN(model, XkbModel, XKB_DFLT_MODEL) 495706f2543SmrgGEN(layout, XkbLayout, XKB_DFLT_LAYOUT) 496706f2543SmrgGEN(variant, XkbVariant, XKB_DFLT_VARIANT) 497706f2543SmrgGEN(options, XkbOptions, XKB_DFLT_OPTIONS) 498