1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2002-2003 Red Hat Inc., Durham, North Carolina.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * All Rights Reserved.
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining
7*4882a593Smuzhiyun * a copy of this software and associated documentation files (the
8*4882a593Smuzhiyun * "Software"), to deal in the Software without restriction, including
9*4882a593Smuzhiyun * without limitation on the rights to use, copy, modify, merge,
10*4882a593Smuzhiyun * publish, distribute, sublicense, and/or sell copies of the Software,
11*4882a593Smuzhiyun * and to permit persons to whom the Software is furnished to do so,
12*4882a593Smuzhiyun * subject to the following conditions:
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun * The above copyright notice and this permission notice (including the
15*4882a593Smuzhiyun * next paragraph) shall be included in all copies or substantial
16*4882a593Smuzhiyun * portions of the Software.
17*4882a593Smuzhiyun *
18*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19*4882a593Smuzhiyun * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20*4882a593Smuzhiyun * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21*4882a593Smuzhiyun * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22*4882a593Smuzhiyun * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23*4882a593Smuzhiyun * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24*4882a593Smuzhiyun * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25*4882a593Smuzhiyun * SOFTWARE.
26*4882a593Smuzhiyun */
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun /*
29*4882a593Smuzhiyun * Authors:
30*4882a593Smuzhiyun * Rickard E. (Rik) Faith <faith@redhat.com>
31*4882a593Smuzhiyun *
32*4882a593Smuzhiyun */
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun /** \file
35*4882a593Smuzhiyun * Provides interface for reading DMX configuration files and for
36*4882a593Smuzhiyun * combining that information with command-line configuration parameters. */
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun #ifdef HAVE_DMX_CONFIG_H
39*4882a593Smuzhiyun #include <dmx-config.h>
40*4882a593Smuzhiyun #endif
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun #include "dmx.h"
43*4882a593Smuzhiyun #include "dmxinput.h"
44*4882a593Smuzhiyun #include "dmxconfig.h"
45*4882a593Smuzhiyun #include "dmxparse.h"
46*4882a593Smuzhiyun #include "dmxlog.h"
47*4882a593Smuzhiyun #include "dmxcb.h"
48*4882a593Smuzhiyun #include "dmxstat.h"
49*4882a593Smuzhiyun #include "parser.h"
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun extern int yydebug;
52*4882a593Smuzhiyun extern FILE *yyin;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun static char *dmxXkbRules;
55*4882a593Smuzhiyun static char *dmxXkbModel;
56*4882a593Smuzhiyun static char *dmxXkbLayout;
57*4882a593Smuzhiyun static char *dmxXkbVariant;
58*4882a593Smuzhiyun static char *dmxXkbOptions;
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun /** Stores lists of configuration information. */
61*4882a593Smuzhiyun typedef struct DMXConfigListStruct {
62*4882a593Smuzhiyun const char *name;
63*4882a593Smuzhiyun struct DMXConfigListStruct *next;
64*4882a593Smuzhiyun } DMXConfigList, *DMXConfigListPtr;
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun /** This stucture stores the parsed configuration information. */
67*4882a593Smuzhiyun typedef struct DMXConfigCmdStruct {
68*4882a593Smuzhiyun const char *filename;
69*4882a593Smuzhiyun const char *config;
70*4882a593Smuzhiyun DMXConfigList *displays;
71*4882a593Smuzhiyun DMXConfigList *inputs;
72*4882a593Smuzhiyun DMXConfigList *xinputs;
73*4882a593Smuzhiyun } DMXConfigCmd, *DMXConfigCmdPtr;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun extern DMXConfigEntryPtr dmxConfigEntry;
76*4882a593Smuzhiyun static DMXConfigCmd dmxConfigCmd;
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun static int dmxDisplaysFromCommandLine;
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun /** Make a note that \a display is the name of an X11 display that
81*4882a593Smuzhiyun * should be initialized as a backend (output) display. Called from
82*4882a593Smuzhiyun * #ddxProcessArgument. */
83*4882a593Smuzhiyun void
dmxConfigStoreDisplay(const char * display)84*4882a593Smuzhiyun dmxConfigStoreDisplay(const char *display)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun DMXConfigListPtr entry = malloc(sizeof(*entry));
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun entry->name = strdup(display);
89*4882a593Smuzhiyun entry->next = NULL;
90*4882a593Smuzhiyun if (!dmxConfigCmd.displays)
91*4882a593Smuzhiyun dmxConfigCmd.displays = entry;
92*4882a593Smuzhiyun else {
93*4882a593Smuzhiyun DMXConfigList *pt;
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun for (pt = dmxConfigCmd.displays; pt->next; pt = pt->next);
96*4882a593Smuzhiyun if (!pt)
97*4882a593Smuzhiyun dmxLog(dmxFatal, "dmxConfigStoreDisplay: end of list non-NULL\n");
98*4882a593Smuzhiyun pt->next = entry;
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun ++dmxDisplaysFromCommandLine;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun /** Make a note that \a input is the name of an X11 display that should
104*4882a593Smuzhiyun * be used for input (either a backend or a console input device). */
105*4882a593Smuzhiyun void
dmxConfigStoreInput(const char * input)106*4882a593Smuzhiyun dmxConfigStoreInput(const char *input)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun DMXConfigListPtr entry = malloc(sizeof(*entry));
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun entry->name = strdup(input);
111*4882a593Smuzhiyun entry->next = NULL;
112*4882a593Smuzhiyun if (!dmxConfigCmd.inputs)
113*4882a593Smuzhiyun dmxConfigCmd.inputs = entry;
114*4882a593Smuzhiyun else {
115*4882a593Smuzhiyun DMXConfigList *pt;
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun for (pt = dmxConfigCmd.inputs; pt->next; pt = pt->next);
118*4882a593Smuzhiyun if (!pt)
119*4882a593Smuzhiyun dmxLog(dmxFatal, "dmxConfigStoreInput: end of list non-NULL\n");
120*4882a593Smuzhiyun pt->next = entry;
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun /** Make a note that \a input is the name of an X11 display that should
125*4882a593Smuzhiyun * be used for input from XInput extension devices. */
126*4882a593Smuzhiyun void
dmxConfigStoreXInput(const char * input)127*4882a593Smuzhiyun dmxConfigStoreXInput(const char *input)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun DMXConfigListPtr entry = malloc(sizeof(*entry));
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun entry->name = strdup(input);
132*4882a593Smuzhiyun entry->next = NULL;
133*4882a593Smuzhiyun if (!dmxConfigCmd.xinputs)
134*4882a593Smuzhiyun dmxConfigCmd.xinputs = entry;
135*4882a593Smuzhiyun else {
136*4882a593Smuzhiyun DMXConfigList *pt;
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun for (pt = dmxConfigCmd.xinputs; pt->next; pt = pt->next);
139*4882a593Smuzhiyun if (!pt)
140*4882a593Smuzhiyun dmxLog(dmxFatal, "dmxConfigStoreXInput: end of list non-NULL\n");
141*4882a593Smuzhiyun pt->next = entry;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun /** Make a note that \a file is the configuration file. */
146*4882a593Smuzhiyun void
dmxConfigStoreFile(const char * file)147*4882a593Smuzhiyun dmxConfigStoreFile(const char *file)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun if (dmxConfigCmd.filename)
150*4882a593Smuzhiyun dmxLog(dmxFatal, "Only one -configfile allowed\n");
151*4882a593Smuzhiyun dmxConfigCmd.filename = strdup(file);
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun /** Make a note that \a config should be used as the configuration for
155*4882a593Smuzhiyun * current instantiation of the DMX server. */
156*4882a593Smuzhiyun void
dmxConfigStoreConfig(const char * config)157*4882a593Smuzhiyun dmxConfigStoreConfig(const char *config)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun if (dmxConfigCmd.config)
160*4882a593Smuzhiyun dmxLog(dmxFatal, "Only one -config allowed\n");
161*4882a593Smuzhiyun dmxConfigCmd.config = strdup(config);
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun static int
dmxConfigReadFile(const char * filename,int debug)165*4882a593Smuzhiyun dmxConfigReadFile(const char *filename, int debug)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun FILE *str;
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun if (!(str = fopen(filename, "r")))
170*4882a593Smuzhiyun return -1;
171*4882a593Smuzhiyun dmxLog(dmxInfo, "Reading configuration file \"%s\"\n", filename);
172*4882a593Smuzhiyun yyin = str;
173*4882a593Smuzhiyun yydebug = debug;
174*4882a593Smuzhiyun yyparse();
175*4882a593Smuzhiyun fclose(str);
176*4882a593Smuzhiyun return 0;
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun static const char *
dmxConfigMatch(const char * target,DMXConfigEntryPtr entry)180*4882a593Smuzhiyun dmxConfigMatch(const char *target, DMXConfigEntryPtr entry)
181*4882a593Smuzhiyun {
182*4882a593Smuzhiyun DMXConfigVirtualPtr v = entry->virtual;
183*4882a593Smuzhiyun const char *name = NULL;
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun if (v && v->name)
186*4882a593Smuzhiyun name = v->name;
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun if (v && !dmxConfigCmd.config)
189*4882a593Smuzhiyun return v->name ? v->name : "<noname>";
190*4882a593Smuzhiyun if (!name)
191*4882a593Smuzhiyun return NULL;
192*4882a593Smuzhiyun if (!strcmp(name, target))
193*4882a593Smuzhiyun return name;
194*4882a593Smuzhiyun return NULL;
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun 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)198*4882a593Smuzhiyun dmxConfigAddDisplay(const char *name,
199*4882a593Smuzhiyun int scrnWidth, int scrnHeight,
200*4882a593Smuzhiyun int scrnX, int scrnY,
201*4882a593Smuzhiyun int scrnXSign, int scrnYSign,
202*4882a593Smuzhiyun int rootWidth, int rootHeight,
203*4882a593Smuzhiyun int rootX, int rootY, int rootXSign, int rootYSign)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun DMXScreenInfo *dmxScreen;
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun if (!(dmxScreens = reallocarray(dmxScreens, dmxNumScreens + 1,
208*4882a593Smuzhiyun sizeof(*dmxScreens))))
209*4882a593Smuzhiyun dmxLog(dmxFatal,
210*4882a593Smuzhiyun "dmxConfigAddDisplay: realloc failed for screen %d (%s)\n",
211*4882a593Smuzhiyun dmxNumScreens, name);
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun dmxScreen = &dmxScreens[dmxNumScreens];
214*4882a593Smuzhiyun memset(dmxScreen, 0, sizeof(*dmxScreen));
215*4882a593Smuzhiyun dmxScreen->name = name;
216*4882a593Smuzhiyun dmxScreen->index = dmxNumScreens;
217*4882a593Smuzhiyun dmxScreen->scrnWidth = scrnWidth;
218*4882a593Smuzhiyun dmxScreen->scrnHeight = scrnHeight;
219*4882a593Smuzhiyun dmxScreen->scrnX = scrnX;
220*4882a593Smuzhiyun dmxScreen->scrnY = scrnY;
221*4882a593Smuzhiyun dmxScreen->scrnXSign = scrnXSign;
222*4882a593Smuzhiyun dmxScreen->scrnYSign = scrnYSign;
223*4882a593Smuzhiyun dmxScreen->rootWidth = rootWidth;
224*4882a593Smuzhiyun dmxScreen->rootHeight = rootHeight;
225*4882a593Smuzhiyun dmxScreen->rootX = rootX;
226*4882a593Smuzhiyun dmxScreen->rootY = rootY;
227*4882a593Smuzhiyun dmxScreen->stat = dmxStatAlloc();
228*4882a593Smuzhiyun ++dmxNumScreens;
229*4882a593Smuzhiyun return dmxScreen;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun DMXInputInfo *
dmxConfigAddInput(const char * name,int core)233*4882a593Smuzhiyun dmxConfigAddInput(const char *name, int core)
234*4882a593Smuzhiyun {
235*4882a593Smuzhiyun DMXInputInfo *dmxInput;
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun if (!(dmxInputs = reallocarray(dmxInputs, dmxNumInputs + 1,
238*4882a593Smuzhiyun sizeof(*dmxInputs))))
239*4882a593Smuzhiyun dmxLog(dmxFatal,
240*4882a593Smuzhiyun "dmxConfigAddInput: realloc failed for input %d (%s)\n",
241*4882a593Smuzhiyun dmxNumInputs, name);
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun dmxInput = &dmxInputs[dmxNumInputs];
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun memset(dmxInput, 0, sizeof(*dmxInput));
246*4882a593Smuzhiyun dmxInput->name = name;
247*4882a593Smuzhiyun dmxInput->inputIdx = dmxNumInputs;
248*4882a593Smuzhiyun dmxInput->scrnIdx = -1;
249*4882a593Smuzhiyun dmxInput->core = core;
250*4882a593Smuzhiyun ++dmxNumInputs;
251*4882a593Smuzhiyun return dmxInput;
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun static void
dmxConfigCopyFromDisplay(DMXConfigDisplayPtr d)255*4882a593Smuzhiyun dmxConfigCopyFromDisplay(DMXConfigDisplayPtr d)
256*4882a593Smuzhiyun {
257*4882a593Smuzhiyun DMXScreenInfo *dmxScreen;
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun dmxScreen = dmxConfigAddDisplay(d->name,
260*4882a593Smuzhiyun d->scrnWidth, d->scrnHeight,
261*4882a593Smuzhiyun d->scrnX, d->scrnY,
262*4882a593Smuzhiyun d->scrnXSign, d->scrnYSign,
263*4882a593Smuzhiyun d->rootWidth, d->rootHeight,
264*4882a593Smuzhiyun d->rootX, d->rootY,
265*4882a593Smuzhiyun d->rootXSign, d->rootXSign);
266*4882a593Smuzhiyun dmxScreen->where = PosAbsolute;
267*4882a593Smuzhiyun dmxScreen->whereX = d->rootXOrigin;
268*4882a593Smuzhiyun dmxScreen->whereY = d->rootYOrigin;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun static void
dmxConfigCopyFromWall(DMXConfigWallPtr w)272*4882a593Smuzhiyun dmxConfigCopyFromWall(DMXConfigWallPtr w)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun DMXConfigStringPtr pt;
275*4882a593Smuzhiyun DMXScreenInfo *dmxScreen;
276*4882a593Smuzhiyun int edge = dmxNumScreens;
277*4882a593Smuzhiyun int last = dmxNumScreens;
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun if (!w->xwall && !w->ywall) { /* Try to make it square */
280*4882a593Smuzhiyun int count;
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun for (pt = w->nameList, count = 0; pt; pt = pt->next)
283*4882a593Smuzhiyun ++count;
284*4882a593Smuzhiyun w->xwall = sqrt(count) + .5;
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun for (pt = w->nameList; pt; pt = pt->next) {
288*4882a593Smuzhiyun dmxScreen = dmxConfigAddDisplay(pt->string, w->width, w->height,
289*4882a593Smuzhiyun 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
290*4882a593Smuzhiyun if (pt == w->nameList) { /* Upper left */
291*4882a593Smuzhiyun dmxScreen->where = PosAbsolute;
292*4882a593Smuzhiyun dmxScreen->whereX = 0;
293*4882a593Smuzhiyun dmxScreen->whereY = 0;
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun else if (w->xwall) { /* Tile left to right, then top to bottom */
296*4882a593Smuzhiyun if (!((dmxNumScreens - 1) % w->xwall)) {
297*4882a593Smuzhiyun dmxScreen->where = PosBelow;
298*4882a593Smuzhiyun dmxScreen->whereRefScreen = edge;
299*4882a593Smuzhiyun edge = dmxNumScreens - 1;
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun else {
302*4882a593Smuzhiyun dmxScreen->where = PosRightOf;
303*4882a593Smuzhiyun dmxScreen->whereRefScreen = last;
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun else { /* Tile top to bottom, then left to right */
307*4882a593Smuzhiyun if (!((dmxNumScreens - 1) % w->ywall)) {
308*4882a593Smuzhiyun dmxScreen->where = PosRightOf;
309*4882a593Smuzhiyun dmxScreen->whereRefScreen = edge;
310*4882a593Smuzhiyun edge = dmxNumScreens - 1;
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun else {
313*4882a593Smuzhiyun dmxScreen->where = PosBelow;
314*4882a593Smuzhiyun dmxScreen->whereRefScreen = last;
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun last = dmxNumScreens - 1;
319*4882a593Smuzhiyun if (dmxScreen->where == PosAbsolute)
320*4882a593Smuzhiyun dmxLog(dmxInfo, "Added %s at %d %d\n",
321*4882a593Smuzhiyun pt->string, dmxScreen->whereX, dmxScreen->whereY);
322*4882a593Smuzhiyun else
323*4882a593Smuzhiyun dmxLog(dmxInfo, "Added %s %s %s\n",
324*4882a593Smuzhiyun pt->string,
325*4882a593Smuzhiyun dmxScreen->where == PosBelow ? "below" : "right of",
326*4882a593Smuzhiyun dmxScreens[dmxScreen->whereRefScreen].name);
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun static void
dmxConfigCopyFromOption(DMXConfigOptionPtr o)331*4882a593Smuzhiyun dmxConfigCopyFromOption(DMXConfigOptionPtr o)
332*4882a593Smuzhiyun {
333*4882a593Smuzhiyun DMXConfigStringPtr pt;
334*4882a593Smuzhiyun int argc = 0;
335*4882a593Smuzhiyun char **argv = NULL;
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun if (serverGeneration != 1)
338*4882a593Smuzhiyun return; /* FIXME: only do once, for now */
339*4882a593Smuzhiyun if (!o || !o->string)
340*4882a593Smuzhiyun return;
341*4882a593Smuzhiyun for (pt = o->option; pt; pt = pt->next) {
342*4882a593Smuzhiyun if (pt->string) {
343*4882a593Smuzhiyun ++argc;
344*4882a593Smuzhiyun argv = reallocarray(argv, argc + 1, sizeof(*argv));
345*4882a593Smuzhiyun argv[argc] = (char *) pt->string;
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun argv[0] = NULL;
349*4882a593Smuzhiyun ProcessCommandLine(argc + 1, argv);
350*4882a593Smuzhiyun free(argv);
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun static void
dmxConfigCopyFromParam(DMXConfigParamPtr p)354*4882a593Smuzhiyun dmxConfigCopyFromParam(DMXConfigParamPtr p)
355*4882a593Smuzhiyun {
356*4882a593Smuzhiyun const char **argv;
357*4882a593Smuzhiyun int argc;
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun if ((argv = dmxConfigLookupParam(p, "xkbrules", &argc)) && argc == 2) {
360*4882a593Smuzhiyun dmxConfigSetXkbRules(argv[1]);
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun else if ((argv = dmxConfigLookupParam(p, "xkbmodel", &argc))
363*4882a593Smuzhiyun && argc == 2) {
364*4882a593Smuzhiyun dmxConfigSetXkbModel(argv[1]);
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun else if ((argv = dmxConfigLookupParam(p, "xkblayout", &argc))
367*4882a593Smuzhiyun && argc == 2) {
368*4882a593Smuzhiyun dmxConfigSetXkbLayout(argv[1]);
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun else if ((argv = dmxConfigLookupParam(p, "xkbvariant", &argc))
371*4882a593Smuzhiyun && argc == 2) {
372*4882a593Smuzhiyun dmxConfigSetXkbVariant(argv[1]);
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun else if ((argv = dmxConfigLookupParam(p, "xkboptions", &argc))
375*4882a593Smuzhiyun && argc == 2) {
376*4882a593Smuzhiyun dmxConfigSetXkbOptions(argv[1]);
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun static void
dmxConfigCopyData(DMXConfigVirtualPtr v)381*4882a593Smuzhiyun dmxConfigCopyData(DMXConfigVirtualPtr v)
382*4882a593Smuzhiyun {
383*4882a593Smuzhiyun DMXConfigSubPtr sub;
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun if (v->dim)
386*4882a593Smuzhiyun dmxSetWidthHeight(v->dim->x, v->dim->y);
387*4882a593Smuzhiyun else
388*4882a593Smuzhiyun dmxSetWidthHeight(0, 0);
389*4882a593Smuzhiyun for (sub = v->subentry; sub; sub = sub->next) {
390*4882a593Smuzhiyun switch (sub->type) {
391*4882a593Smuzhiyun case dmxConfigDisplay:
392*4882a593Smuzhiyun dmxConfigCopyFromDisplay(sub->display);
393*4882a593Smuzhiyun break;
394*4882a593Smuzhiyun case dmxConfigWall:
395*4882a593Smuzhiyun dmxConfigCopyFromWall(sub->wall);
396*4882a593Smuzhiyun break;
397*4882a593Smuzhiyun case dmxConfigOption:
398*4882a593Smuzhiyun dmxConfigCopyFromOption(sub->option);
399*4882a593Smuzhiyun break;
400*4882a593Smuzhiyun case dmxConfigParam:
401*4882a593Smuzhiyun dmxConfigCopyFromParam(sub->param);
402*4882a593Smuzhiyun break;
403*4882a593Smuzhiyun default:
404*4882a593Smuzhiyun dmxLog(dmxFatal,
405*4882a593Smuzhiyun "dmxConfigCopyData: not a display, wall, or value\n");
406*4882a593Smuzhiyun }
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun static void
dmxConfigFromCommandLine(void)411*4882a593Smuzhiyun dmxConfigFromCommandLine(void)
412*4882a593Smuzhiyun {
413*4882a593Smuzhiyun DMXConfigListPtr pt;
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun dmxLog(dmxInfo, "Using configuration from command line\n");
416*4882a593Smuzhiyun for (pt = dmxConfigCmd.displays; pt; pt = pt->next) {
417*4882a593Smuzhiyun DMXScreenInfo *dmxScreen = dmxConfigAddDisplay(pt->name,
418*4882a593Smuzhiyun 0, 0, 0, 0, 0, 0,
419*4882a593Smuzhiyun 0, 0, 0, 0, 0, 0);
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun if (dmxNumScreens == 1) {
422*4882a593Smuzhiyun dmxScreen->where = PosAbsolute;
423*4882a593Smuzhiyun dmxScreen->whereX = 0;
424*4882a593Smuzhiyun dmxScreen->whereY = 0;
425*4882a593Smuzhiyun dmxLog(dmxInfo, "Added %s at %d %d\n",
426*4882a593Smuzhiyun dmxScreen->name, dmxScreen->whereX, dmxScreen->whereY);
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun else {
429*4882a593Smuzhiyun dmxScreen->where = PosRightOf;
430*4882a593Smuzhiyun dmxScreen->whereRefScreen = dmxNumScreens - 2;
431*4882a593Smuzhiyun if (dmxScreen->whereRefScreen < 0)
432*4882a593Smuzhiyun dmxScreen->whereRefScreen = 0;
433*4882a593Smuzhiyun dmxLog(dmxInfo, "Added %s %s %s\n",
434*4882a593Smuzhiyun dmxScreen->name,
435*4882a593Smuzhiyun dmxScreen->where == PosBelow ? "below" : "right of",
436*4882a593Smuzhiyun dmxScreens[dmxScreen->whereRefScreen].name);
437*4882a593Smuzhiyun }
438*4882a593Smuzhiyun }
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun static void
dmxConfigFromConfigFile(void)442*4882a593Smuzhiyun dmxConfigFromConfigFile(void)
443*4882a593Smuzhiyun {
444*4882a593Smuzhiyun DMXConfigEntryPtr pt;
445*4882a593Smuzhiyun const char *name;
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun for (pt = dmxConfigEntry; pt; pt = pt->next) {
448*4882a593Smuzhiyun /* FIXME -- if an input is specified, use it */
449*4882a593Smuzhiyun if (pt->type != dmxConfigVirtual)
450*4882a593Smuzhiyun continue;
451*4882a593Smuzhiyun if ((name = dmxConfigMatch(dmxConfigCmd.config, pt))) {
452*4882a593Smuzhiyun dmxLog(dmxInfo, "Using configuration \"%s\"\n", name);
453*4882a593Smuzhiyun dmxConfigCopyData(pt->virtual);
454*4882a593Smuzhiyun return;
455*4882a593Smuzhiyun }
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun dmxLog(dmxFatal, "Could not find configuration \"%s\" in \"%s\"\n",
458*4882a593Smuzhiyun dmxConfigCmd.config, dmxConfigCmd.filename);
459*4882a593Smuzhiyun }
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun static void
dmxConfigConfigInputs(void)462*4882a593Smuzhiyun dmxConfigConfigInputs(void)
463*4882a593Smuzhiyun {
464*4882a593Smuzhiyun DMXConfigListPtr pt;
465*4882a593Smuzhiyun
466*4882a593Smuzhiyun if (dmxNumInputs)
467*4882a593Smuzhiyun return;
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun if (dmxConfigCmd.inputs) { /* Use command line */
470*4882a593Smuzhiyun for (pt = dmxConfigCmd.inputs; pt; pt = pt->next)
471*4882a593Smuzhiyun dmxConfigAddInput(pt->name, TRUE);
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun else if (dmxNumScreens) { /* Use first display */
474*4882a593Smuzhiyun dmxConfigAddInput(dmxScreens[0].name, TRUE);
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun else { /* Use dummy */
477*4882a593Smuzhiyun dmxConfigAddInput("dummy", TRUE);
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun if (dmxConfigCmd.xinputs) { /* Non-core devices from command line */
481*4882a593Smuzhiyun for (pt = dmxConfigCmd.xinputs; pt; pt = pt->next)
482*4882a593Smuzhiyun dmxConfigAddInput(pt->name, FALSE);
483*4882a593Smuzhiyun }
484*4882a593Smuzhiyun }
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun /** Set up the appropriate global variables so that the DMX server will
487*4882a593Smuzhiyun * be initialized using the configuration specified in the config file
488*4882a593Smuzhiyun * and on the command line. */
489*4882a593Smuzhiyun void
dmxConfigConfigure(void)490*4882a593Smuzhiyun dmxConfigConfigure(void)
491*4882a593Smuzhiyun {
492*4882a593Smuzhiyun if (dmxConfigEntry) {
493*4882a593Smuzhiyun dmxConfigFreeEntry(dmxConfigEntry);
494*4882a593Smuzhiyun dmxConfigEntry = NULL;
495*4882a593Smuzhiyun }
496*4882a593Smuzhiyun if (dmxConfigCmd.filename) {
497*4882a593Smuzhiyun if (dmxConfigCmd.displays)
498*4882a593Smuzhiyun dmxLog(dmxWarning,
499*4882a593Smuzhiyun "Using configuration file \"%s\" instead of command line\n",
500*4882a593Smuzhiyun dmxConfigCmd.filename);
501*4882a593Smuzhiyun dmxConfigReadFile(dmxConfigCmd.filename, 0);
502*4882a593Smuzhiyun dmxConfigFromConfigFile();
503*4882a593Smuzhiyun }
504*4882a593Smuzhiyun else {
505*4882a593Smuzhiyun if (dmxConfigCmd.config)
506*4882a593Smuzhiyun dmxLog(dmxWarning,
507*4882a593Smuzhiyun "Configuration name (%s) without configuration file\n",
508*4882a593Smuzhiyun dmxConfigCmd.config);
509*4882a593Smuzhiyun dmxConfigFromCommandLine();
510*4882a593Smuzhiyun }
511*4882a593Smuzhiyun dmxConfigConfigInputs();
512*4882a593Smuzhiyun }
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun /** This function determines the number of displays we WILL have and
515*4882a593Smuzhiyun * sets MAXSCREENS to that value. This is difficult since the number
516*4882a593Smuzhiyun * depends on the command line (which is easy to count) or on the config
517*4882a593Smuzhiyun * file, which has to be parsed. */
518*4882a593Smuzhiyun void
dmxConfigSetMaxScreens(void)519*4882a593Smuzhiyun dmxConfigSetMaxScreens(void)
520*4882a593Smuzhiyun {
521*4882a593Smuzhiyun static int processing = 0;
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun if (processing)
524*4882a593Smuzhiyun return; /* Prevent reentry via ProcessCommandLine */
525*4882a593Smuzhiyun processing = 1;
526*4882a593Smuzhiyun if (dmxConfigCmd.filename) {
527*4882a593Smuzhiyun if (!dmxNumScreens)
528*4882a593Smuzhiyun dmxConfigConfigure();
529*4882a593Smuzhiyun #ifndef MAXSCREENS
530*4882a593Smuzhiyun SetMaxScreens(dmxNumScreens);
531*4882a593Smuzhiyun #endif
532*4882a593Smuzhiyun }
533*4882a593Smuzhiyun else
534*4882a593Smuzhiyun #ifndef MAXSCREENS
535*4882a593Smuzhiyun SetMaxScreens(dmxDisplaysFromCommandLine);
536*4882a593Smuzhiyun #endif
537*4882a593Smuzhiyun processing = 0;
538*4882a593Smuzhiyun }
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun /** This macro is used to generate the following access methods:
541*4882a593Smuzhiyun * - dmxConfig{Set,Get}rules
542*4882a593Smuzhiyun * - dmxConfig{Set,Get}model
543*4882a593Smuzhiyun * - dmxConfig{Set,Get}layout
544*4882a593Smuzhiyun * - dmxConfig{Set,Get}variant
545*4882a593Smuzhiyun * - dmxConfig{Set,Get}options
546*4882a593Smuzhiyun * These methods are used to read and write information about the keyboard. */
547*4882a593Smuzhiyun
548*4882a593Smuzhiyun #define GEN(param,glob,def) \
549*4882a593Smuzhiyun void dmxConfigSet##glob(const char *param) { \
550*4882a593Smuzhiyun if (dmx##glob) free((void *)dmx##glob); \
551*4882a593Smuzhiyun dmx##glob = strdup(param); \
552*4882a593Smuzhiyun } \
553*4882a593Smuzhiyun char *dmxConfigGet##glob(void) { \
554*4882a593Smuzhiyun return (char *)(dmx##glob ? dmx##glob : def); \
555*4882a593Smuzhiyun }
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun GEN(rules, XkbRules, XKB_DFLT_RULES)
558*4882a593Smuzhiyun GEN(model, XkbModel, XKB_DFLT_MODEL)
559*4882a593Smuzhiyun GEN(layout, XkbLayout, XKB_DFLT_LAYOUT)
560*4882a593Smuzhiyun GEN(variant, XkbVariant, XKB_DFLT_VARIANT)
561*4882a593Smuzhiyun GEN(options, XkbOptions, XKB_DFLT_OPTIONS)
562