3 Copyright 1988, 1998 The Open Group
4 Copyright 2000-2005 Oswald Buddenhagen <ossi@kde.org>
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
12 The above copyright notice and this permission notice shall be included
13 in all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 OTHER DEALINGS IN THE SOFTWARE.
23 Except as contained in this notice, the name of a copyright holder shall
24 not be used in advertising or otherwise to promote the sale, use or
25 other dealings in this Software without prior written authorization
26 from the copyright holder.
31 * xdm - display manager daemon
32 * Author: Keith Packard, MIT X Consortium
34 * obtain configuration data
42 #define WANT_CORE_DEFS
45 static char **originalArgv
;
56 originalArgv
, "_config", 0, strdup( "config reader" ),
58 logPanic( "Cannot run config reader\n" );
59 debug( "getter now ready\n" );
68 (void)gClose( &getter
, 0, False
);
69 debug( "getter now closed\n" );
74 * ref-counted, unique-instance strings
79 * make a ref-counted string of the argument. the new string will
80 * have a ref-count of 1. the passed string pointer is no longer valid.
87 for (cs
= strs
; cs
; cs
= cs
->next
)
88 if (!strcmp( str
, cs
->str
)) {
93 if (!(cs
= Malloc( sizeof(*cs
) )))
103 * decrement ref-count and delete string when count drops to 0.
110 if (!str
|| --str
->cnt
)
112 for (cs
= &strs
; *cs
; cs
= &((*cs
)->next
))
122 typedef struct CfgFile
{
128 static int numCfgFiles
;
129 static CfgFile
*cfgFiles
;
131 static int cfgMapT
[] = {
138 static int cfgMap
[as(cfgMapT
)];
143 int ncf
, i
, dep
, ret
;
147 gSendInt( GC_Files
);
149 if (!(cf
= Malloc( ncf
* sizeof(*cf
) ))) {
153 for (i
= 0; i
< ncf
; i
++) {
154 cf
[i
].name
= newStr( gRecvStr() );
155 if ((dep
= cf
[i
].depidx
= gRecvInt()) != -1)
156 cf
[i
].deptime
= mTime( cf
[dep
].name
->str
);
159 for (i
= 0; i
< numCfgFiles
; i
++)
160 delStr( cfgFiles
[i
].name
);
166 for (i
= 0; i
< as(cfgMapT
); i
++) {
167 gSendInt( cfgMapT
[i
] );
168 if ((cfgMap
[i
] = gRecvInt()) < 0) {
169 logError( "Config reader does not support config cathegory %#x\n",
183 if ((dep
= cfgFiles
[idx
].depidx
) == -1)
187 return mTime( cfgFiles
[dep
].name
->str
) != cfgFiles
[idx
].deptime
;
191 needsReScan( int what
, CfgDep
*dep
)
196 for (widx
= 0; cfgMapT
[widx
] != what
; widx
++);
198 if (checkDep( idx
)) {
203 mt
= mTime( cfgFiles
[idx
].name
->str
);
204 if (dep
->name
!= cfgFiles
[idx
].name
) {
207 dep
->name
= cfgFiles
[idx
].name
;
211 } else if (dep
->time
!= mt
) {
219 startConfig( int what
, CfgDep
*dep
, int force
)
223 if ((ret
= needsReScan( what
, dep
)) < 0 || (!ret
&& !force
))
226 gSendInt( GC_GetConf
);
228 gSendStr( dep
->name
->str
);
233 loadResources( CfgArr
*conf
)
235 char **vptr
, **pptr
, *cptr
;
236 int *iptr
, i
, id
, nu
, j
, nptr
, nint
, nchr
;
240 conf
->numCfgEnt
= gRecvInt();
244 if (!(conf
->data
= Malloc( conf
->numCfgEnt
*
247 nptr
* sizeof(char *) +
254 vptr
= (char **)conf
->data
;
255 pptr
= vptr
+ conf
->numCfgEnt
;
256 conf
->idx
= (int *)(pptr
+ nptr
);
257 iptr
= conf
->idx
+ conf
->numCfgEnt
;
258 cptr
= (char *)(iptr
+ nint
);
259 for (i
= 0; i
< conf
->numCfgEnt
; i
++) {
262 switch (id
& C_TYPE_MASK
) {
264 vptr
[i
] = (char *)((unsigned long)gRecvInt());
268 cptr
+= gRecvStrBuf( cptr
);
272 vptr
[i
] = (char *)pptr
;
273 for (j
= 0; j
< nu
; j
++) {
275 cptr
+= gRecvStrBuf( cptr
);
280 logError( "Config reader supplied unknown data type in id %#x\n",
288 applyResource( int id
, void **src
, void **dst
)
290 switch (id
& C_TYPE_MASK
) {
292 *(int *)dst
= *(int *)src
;
296 *(char **)dst
= *(char **)src
;
302 #define boffset(f) offsetof(struct display, f)
304 /* no global variables exported currently
312 /* no per-display variables exported currently
323 findCfgEnt( struct display
*d
, int id
)
327 /* no global variables exported currently
328 for (i = 0; i < as(globEnt); i++)
329 if (globEnt[i].id == id)
330 return globEnt[i].off;
332 for (i
= 0; i
< cfg
.numCfgEnt
; i
++)
333 if (cfg
.idx
[i
] == id
)
334 return ((void **)cfg
.data
) + i
;
336 /* no per-display variables exported currently
337 for (i = 0; i < as(dpyEnt); i++)
338 if (dpyEnt[i].id == id)
339 return (char **)(((char *)d) + dpyEnt[i].off);
341 for (i
= 0; i
< d
->cfg
.numCfgEnt
; i
++)
342 if (d
->cfg
.idx
[i
] == id
)
343 return ((void **)d
->cfg
.data
) + i
;
345 debug( "unknown config entry %#x requested\n", id
);
350 CONF_CORE_GLOBAL_DEFS
360 loadDMResources( int force
)
365 if (Setjmp( cnftalk
.errjmp
))
366 return -1; /* may memleak, but we probably have to abort anyway */
367 if ((ret
= startConfig( GC_gGlobal
, &cfg
.dep
, force
)) <= 0)
369 loadResources( &cfg
);
370 /* debug( "manager resources: %[*x\n",
371 cfg.numCfgEnt, ((char **)cfg.data) + cfg.numCfgEnt );*/
373 for (i
= 0; i
< as(globVal
); i
++) {
374 if (!(ent
= findCfgEnt( 0, globVal
[i
].id
)))
377 applyResource( globVal
[i
].id
, ent
, (void **)globVal
[i
].ptr
);
380 logError( "Internal error: config reader supplied incomplete data\n" );
393 loadDisplayResources( struct display
*d
)
398 if (Setjmp( cnftalk
.errjmp
))
399 return -1; /* may memleak */
400 if ((ret
= startConfig( GC_gDisplay
, &d
->cfg
.dep
, False
)) <= 0)
403 gSendStr( d
->class2
);
404 loadResources( &d
->cfg
);
405 /* debug( "display(%s, %s) resources: %[*x\n", d->name, d->class2,
406 d->cfg.numCfgEnt, ((char **)d->cfg.data) + d->cfg.numCfgEnt );*/
408 for (i
= 0; i
< as(dpyVal
); i
++) {
409 if (!(ent
= findCfgEnt( d
, dpyVal
[i
].id
)))
412 applyResource( dpyVal
[i
].id
, ent
,
413 (void **)(((char *)d
) + dpyVal
[i
].off
) );
416 logError( "Internal error: config reader supplied incomplete data\n" );
421 initResources( char **argv
)
424 cnftalk
.pipe
= &getter
.pipe
;
425 if (Setjmp( cnftalk
.errjmp
))
426 return False
; /* may memleak */
431 addServers( char **srv
, int bType
)
434 const char *dtx
, *cls
;
437 for (; *srv
; srv
++) {
438 if ((cls
= strchr( *srv
, '_' ))) {
439 if (!strNDup( &name
, *srv
, cls
- *srv
))
441 if (!strDup( &class2
, cls
)) {
446 if (!strDup( &name
, *srv
))
450 if ((d
= findDisplayByName( name
))) {
455 if (!(d
= newDisplay( name
))) {
463 d
->stillThere
= True
;
465 d
->displayType
= (*name
== ':' ? dLocal
: dForeign
) | bType
;
466 if ((bType
& d_lifetime
) == dReserve
) {
467 if (d
->status
== notRunning
)
470 if (d
->status
== reserve
)
471 d
->status
= notRunning
;
473 debug( "found %s %s%s display: %s %s\n", dtx
,
474 ((d
->displayType
& d_location
) == dLocal
) ? "local" : "foreign",
475 ((d
->displayType
& d_lifetime
) == dReserve
) ? " reserve" : "",
476 d
->name
, d
->class2
);
484 debug( "scanServers\n" );
485 addServers( staticServers
, dFromFile
| dPermanent
);
486 addServers( reserveServers
, dFromFile
| dReserve
);