~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/xfree86/utils/xorgcfg/expert.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
 
3
 * 
 
4
 * Permission is hereby granted, free of charge, to any person obtaining a
 
5
 * copy of this software and associated documentation files (the "Software"),
 
6
 * to deal in the Software without restriction, including without limitation
 
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
8
 * and/or sell copies of the Software, and to permit persons to whom the
 
9
 * Software is furnished to do so, subject to the following conditions:
 
10
 * 
 
11
 * The above copyright notice and this permission notice shall be included in
 
12
 * all copies or substantial portions of the Software.
 
13
 *  
 
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
17
 * CONECTIVA LINUX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 
18
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 
19
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 
20
 * SOFTWARE.
 
21
 * 
 
22
 * Except as contained in this notice, the name of Conectiva Linux shall
 
23
 * not be used in advertising or otherwise to promote the sale, use or other
 
24
 * dealings in this Software without prior written authorization from
 
25
 * Conectiva Linux.
 
26
 *
 
27
 * Author: Paulo CĆ©sar Pereira de Andrade <pcpa@conectiva.com.br>
 
28
 *
 
29
 * $XFree86: xc/programs/Xserver/hw/xfree86/xf86cfg/expert.c,v 1.14tsi Exp $
 
30
 */
 
31
 
 
32
#include "config.h"
 
33
#include "xf86config.h"
 
34
#include "options.h"
 
35
#include "screen.h"
 
36
#include "vidmode.h"
 
37
#include "monitor-cfg.h"
 
38
#include <X11/Shell.h>
 
39
#include <X11/CompositeP.h>
 
40
#include <X11/Xaw/AsciiText.h>
 
41
#include <X11/Xaw/Box.h>
 
42
#include <X11/Xaw/Command.h>
 
43
#include <X11/Xaw/Form.h>
 
44
#include <X11/Xaw/Label.h>
 
45
#include <X11/Xaw/MenuButton.h>
 
46
#include <X11/Xaw/Paned.h>
 
47
#include <X11/Xaw/Panner.h>
 
48
#include <X11/Xaw/Porthole.h>
 
49
#include <X11/Xaw/SimpleMenu.h>
 
50
#include <X11/Xaw/SmeBSB.h>
 
51
#include <X11/Xaw/Toggle.h>
 
52
#include <X11/Xaw/Tree.h>
 
53
#include <ctype.h>
 
54
 
 
55
/*
 
56
 * Types
 
57
 */
 
58
typedef struct _TreeNode TreeNode;
 
59
typedef union _TreeData TreeData;
 
60
typedef void (*NodeDeleteFunc)(TreeNode*);
 
61
typedef void (*NodeUpdateFunc)(TreeNode*);
 
62
 
 
63
union _TreeData {
 
64
    struct {
 
65
        Widget text;
 
66
    } files;
 
67
    struct {
 
68
        Widget text;
 
69
        XF86LoadPtr load;
 
70
    } module;
 
71
    struct {
 
72
        Widget text;
 
73
        XF86ConfModesPtr modes;
 
74
    } modes;
 
75
    struct {
 
76
        Widget text, value;
 
77
        XF86ConfModeLinePtr modeline;
 
78
    } modeline;
 
79
    struct {
 
80
        Widget text, vendor, board, busid, driver;
 
81
        XF86ConfVideoAdaptorPtr video;
 
82
    } video;
 
83
    struct {
 
84
        Widget text;
 
85
        XF86ConfVideoPortPtr port;
 
86
    } port;
 
87
    struct {
 
88
        Widget text, vendor, model, width, height, hsync, vrefresh,
 
89
               gammaRed, gammaGreen, gammaBlue;
 
90
        XF86ConfMonitorPtr monitor;
 
91
    } monitor;
 
92
    struct {
 
93
        Widget menu;
 
94
        XF86ConfModesLinkPtr modeslink;
 
95
    } modeslink;
 
96
    struct {
 
97
        Widget text, vendor, board, chipset, busid, card, driver, ramdac,
 
98
               dacSpeed, videoRam, textClockFreq, biosBase, memBase, ioBase,
 
99
               clockChip, devClock, chipId, chipRev, irq, screen;
 
100
        XF86ConfDevicePtr device;
 
101
    } device;
 
102
    struct {
 
103
        Widget text, defaultDepth, defaultBpp, defaultFbBpp,
 
104
               monitor, device;
 
105
        XF86ConfScreenPtr screen;
 
106
    } screen;
 
107
    struct {
 
108
        Widget menu;
 
109
        XF86ConfAdaptorLinkPtr adaptorlink;
 
110
    } adaptorlink;
 
111
    struct {
 
112
        Widget viewport, c_virtual, depth, bpp, visual, weight, black, white;
 
113
        XF86ConfDisplayPtr display;
 
114
    } display;
 
115
    struct {
 
116
        Widget text;
 
117
        XF86ModePtr mode;
 
118
    } mode;
 
119
    struct {
 
120
        Widget text;
 
121
        XF86ConfInputPtr input;
 
122
    } input;
 
123
    struct {
 
124
        Widget text;
 
125
        XF86ConfLayoutPtr layout;
 
126
    } layout;
 
127
    struct {
 
128
        Widget menu, button, scrnum, adjx, adjy;
 
129
        XF86ConfScreenPtr screen;
 
130
        XF86ConfAdjacencyPtr adjacency;
 
131
    } adjacency;
 
132
    struct {
 
133
        Widget menu;
 
134
        XF86ConfInputrefPtr inputref;
 
135
    } inputref;
 
136
    struct {
 
137
        Widget text;
 
138
        XF86ConfVendorPtr vendor;
 
139
    } vendor;
 
140
    struct {
 
141
        Widget text;
 
142
        XF86ConfVendSubPtr vendsub;
 
143
    } vendsub;
 
144
    struct {
 
145
        Widget name, group, mode;
 
146
        XF86ConfDRIPtr dri;
 
147
    } dri;
 
148
    struct {
 
149
        Widget count, size, flags;
 
150
        XF86ConfBuffersPtr buffers;
 
151
    } buffers;
 
152
};
 
153
 
 
154
struct _TreeNode {
 
155
    Widget node, toggle, treeParent;
 
156
    TreeNode *parent, *child, *next;
 
157
    TreeData *data;
 
158
    NodeDeleteFunc destroy;
 
159
    NodeUpdateFunc update;
 
160
};
 
161
 
 
162
/*
 
163
 * Prototypes
 
164
 */
 
165
static Bool ExpertInitialize(void);
 
166
static TreeNode *NewNode(TreeNode*, Widget, Widget, Widget, TreeData*);
 
167
static void DeleteNode(TreeNode*);
 
168
static void DestroyCallback(Widget, XtPointer, XtPointer);
 
169
static void PannerCallback(Widget, XtPointer, XtPointer);
 
170
static void PortholeCallback(Widget, XtPointer, XtPointer);
 
171
static void ToggleCallback(Widget, XtPointer, XtPointer);
 
172
static void ToggleNode(TreeNode*, Bool);
 
173
static void ToggleNodeRecursive(TreeNode*);
 
174
static void OptionsCallback(Widget, XtPointer, XtPointer);
 
175
static void RelayoutTree(void);
 
176
static void PopdownCallback(Widget, XtPointer, XtPointer);
 
177
static void UpdateConfig(TreeNode*);
 
178
static void DestroyTree(TreeNode*);
 
179
 
 
180
static void CreateFiles(TreeNode*);
 
181
static void CreateFilesField(TreeNode*, char*, char*);
 
182
static void UpdateFiles(TreeNode*);
 
183
 
 
184
static void CreateFontPath(TreeNode*, char*);
 
185
static Widget CreateFontPathField(TreeNode*, char*, Bool);
 
186
static void FontPathChanged(TreeNode*);
 
187
static void NewFontPathCallback(Widget, XtPointer, XtPointer);
 
188
static void FontPathCallback(Widget, XtPointer, XtPointer);
 
189
 
 
190
static void CreateModulePath(TreeNode*, char*);
 
191
static Widget CreateModulePathField(TreeNode*, char*, Bool);
 
192
static void ModulePathChanged(TreeNode*);
 
193
static void NewModulePathCallback(Widget, XtPointer, XtPointer);
 
194
 
 
195
static void CreateModule(TreeNode*, XF86LoadPtr);
 
196
static void CreateModuleField(TreeNode*, Bool);
 
197
static void ModuleDestroy(TreeNode*);
 
198
static void NewModuleCallback(Widget, XtPointer, XtPointer);
 
199
 
 
200
static void CreateModes(TreeNode*, XF86ConfModesPtr);
 
201
static void CreateModesField(TreeNode*, Bool);
 
202
static void ModesDestroy(TreeNode*);
 
203
static void NewModesCallback(Widget, XtPointer, XtPointer);
 
204
static void CreateModesModeLine(TreeNode*, XF86ConfModeLinePtr);
 
205
static void ModesModeLineDestroy(TreeNode*);
 
206
static void NewModesModeLineCallback(Widget, XtPointer, XtPointer);
 
207
 
 
208
static void CreateModeLineField(TreeNode*, Bool, Bool);
 
209
static XF86ConfModeLinePtr ParseModeLine(char*, char*);
 
210
 
 
211
static void CreateVideoAdaptor(TreeNode*, XF86ConfVideoAdaptorPtr);
 
212
static void CreateVideoAdaptorField(TreeNode*, Bool);
 
213
static void VideoAdaptorDestroy(TreeNode*);
 
214
static void NewVideoAdaptorCallback(Widget, XtPointer, XtPointer);
 
215
static void VideoAdaptorUpdate(TreeNode*);
 
216
static void CreateVideoPort(TreeNode*, XF86ConfVideoPortPtr);
 
217
static void CreateVideoPortField(TreeNode*, Bool);
 
218
static void VideoPortDestroy(TreeNode*);
 
219
static void NewVideoPortCallback(Widget, XtPointer, XtPointer);
 
220
 
 
221
static void CreateMonitor(TreeNode*, XF86ConfMonitorPtr);
 
222
static void CreateMonitorField(TreeNode*, Bool);
 
223
static void MonitorDestroy(TreeNode*);
 
224
static void NewMonitorCallback(Widget, XtPointer, XtPointer);
 
225
static void MonitorUpdate(TreeNode*);
 
226
static void CreateMonitorModeLine(TreeNode*, XF86ConfModeLinePtr);
 
227
static void MonitorModeLineDestroy(TreeNode*);
 
228
static void NewMonitorModeLineCallback(Widget, XtPointer, XtPointer);
 
229
static void CreateMonitorModes(TreeNode*, XF86ConfModesLinkPtr);
 
230
static void CreateMonitorModesField(TreeNode*, Bool);
 
231
static void MonitorModesLinkDestroy(TreeNode*);
 
232
static void NewMonitorModesCallback(Widget, XtPointer, XtPointer);
 
233
 
 
234
static void CreateDevice(TreeNode*, XF86ConfDevicePtr);
 
235
static void CreateDeviceField(TreeNode*, Bool);
 
236
static void NewDeviceCallback(Widget, XtPointer, XtPointer);
 
237
static void DeviceDestroy(TreeNode*);
 
238
static void DeviceUpdate(TreeNode*);
 
239
 
 
240
static void CreateScreen(TreeNode*, XF86ConfScreenPtr);
 
241
static void CreateScreenField(TreeNode*, Bool);
 
242
static void NewScreenCallback(Widget, XtPointer, XtPointer);
 
243
static void ScreenDestroy(TreeNode*);
 
244
static void ScreenUpdate(TreeNode*);
 
245
static void CreateScreenAdaptor(TreeNode*, XF86ConfAdaptorLinkPtr);
 
246
static void CreateScreenAdaptorField(TreeNode*, Bool);
 
247
static void NewScreenAdaptorCallback(Widget, XtPointer, XtPointer);
 
248
static void ScreenAdaptorDestroy(TreeNode*);
 
249
static void CreateScreenDisplay(TreeNode*, XF86ConfDisplayPtr);
 
250
static void CreateScreenDisplayField(TreeNode*, Bool);
 
251
static void NewScreenDisplayCallback(Widget, XtPointer, XtPointer);
 
252
static void ScreenDisplayDestroy(TreeNode*);
 
253
static void ScreenDisplayUpdate(TreeNode*);
 
254
static void CreateDisplayMode(TreeNode*, XF86ModePtr);
 
255
static void CreateDisplayModeField(TreeNode*, Bool);
 
256
static void NewDisplayModeCallback(Widget, XtPointer, XtPointer);
 
257
static void DisplayModeDestroy(TreeNode*);
 
258
 
 
259
static void CreateInput(TreeNode*, XF86ConfInputPtr);
 
260
static void CreateInputField(TreeNode*, Bool);
 
261
static void InputDestroy(TreeNode*);
 
262
static void NewInputCallback(Widget, XtPointer, XtPointer);
 
263
static void InputUpdate(TreeNode*);
 
264
 
 
265
static void CreateLayout(TreeNode*, XF86ConfLayoutPtr);
 
266
static void CreateLayoutField(TreeNode*, Bool);
 
267
static void LayoutDestroy(TreeNode*);
 
268
static void NewLayoutCallback(Widget, XtPointer, XtPointer);
 
269
static void CreateAdjacency(TreeNode*, XF86ConfAdjacencyPtr);
 
270
static void CreateAdjacencyField(TreeNode*, Bool);
 
271
static void AdjacencyDestroy(TreeNode*);
 
272
static void NewAdjacencyCallback(Widget, XtPointer, XtPointer);
 
273
static void AdjacencyMenuCallback(Widget, XtPointer, XtPointer);
 
274
static void AdjacencyToggleCallback(Widget, XtPointer, XtPointer);
 
275
static void CreateInputref(TreeNode*, XF86ConfInputrefPtr);
 
276
static void CreateInputrefField(TreeNode*, Bool);
 
277
static void InputrefDestroy(TreeNode*);
 
278
static void NewInputrefCallback(Widget, XtPointer, XtPointer);
 
279
 
 
280
static void CreateVendor(TreeNode*, XF86ConfVendorPtr);
 
281
static void CreateVendorField(TreeNode*, Bool);
 
282
static void VendorDestroy(TreeNode*);
 
283
static void NewVendorCallback(Widget, XtPointer, XtPointer);
 
284
static void CreateVendorSub(TreeNode*, XF86ConfVendSubPtr);
 
285
static void CreateVendorSubField(TreeNode*, Bool);
 
286
static void NewVendorSubCallback(Widget, XtPointer, XtPointer);
 
287
static void VendorSubDestroy(TreeNode*);
 
288
static void VendorSubUpdate(TreeNode*);
 
289
 
 
290
static void CreateDRI(TreeNode*, XF86ConfDRIPtr);
 
291
static void CreateDRIField(TreeNode*);
 
292
static void DRIUpdate(TreeNode*);
 
293
 
 
294
static void CreateBuffers(TreeNode*, XF86ConfBuffersPtr);
 
295
static void CreateBuffersField(TreeNode*, Bool);
 
296
static void BuffersDestroy(TreeNode*);
 
297
static void NewBuffersCallback(Widget, XtPointer, XtPointer);
 
298
static void BuffersUpdate(TreeNode*);
 
299
 
 
300
extern void RemoveDeviceCallback(Widget, XtPointer, XtPointer);
 
301
 
 
302
/* interface.c */
 
303
extern void InitializeDevices(void);
 
304
extern void SelectLayoutCallback(Widget, XtPointer, XtPointer);
 
305
extern void UpdateMenuDeviceList(int);
 
306
extern void SetConfigModeCallback(Widget, XtPointer, XtPointer);
 
307
extern void DefaultLayoutCallback(Widget, XtPointer, XtPointer);
 
308
extern void RemoveLayoutCallback(Widget, XtPointer, XtPointer);
 
309
 
 
310
/*
 
311
 * Initialization
 
312
 */
 
313
static Widget shell, expert, tree, panner;
 
314
extern Widget work, optionsShell, config, layoutp, topMenu;
 
315
extern xf86cfgDevice cpu_device;
 
316
static TreeNode *mainNode, *monitorTree, *screenTree, *layoutTree;
 
317
 
 
318
/*
 
319
 * Implementation
 
320
 */
 
321
void
 
322
ExpertConfigureStart(void)
 
323
{
 
324
    ExpertInitialize();
 
325
 
 
326
    XtPopup(shell, XtGrabExclusive);
 
327
    if (optionsShell == NULL)
 
328
        CreateOptionsShell();
 
329
    XtVaSetValues(optionsShell, XtNtransientFor, shell, NULL);
 
330
}
 
331
 
 
332
void
 
333
ExpertConfigureEnd(void)
 
334
{
 
335
    int i, save_config_mode = config_mode;
 
336
    Widget sme, layopt, layoutsme = NULL;
 
337
    XF86ConfLayoutPtr lay;
 
338
 
 
339
    XtVaSetValues(optionsShell, XtNtransientFor, toplevel, NULL);
 
340
    XtPopdown(shell);
 
341
 
 
342
    /* Need to do this to avoid all code elsewhere needing to update the
 
343
     * "expert" widget tree
 
344
     */
 
345
    UpdateConfig(mainNode);
 
346
    DestroyTree(mainNode);
 
347
    XtDestroyWidget(shell);
 
348
    expert = NULL;
 
349
 
 
350
    if (save_config_mode != CONFIG_LAYOUT)
 
351
        SetConfigModeCallback(topMenu, (XtPointer)CONFIG_LAYOUT, NULL);
 
352
 
 
353
    /* Reset everything as the "expert" interface can do almost anything
 
354
     * to the configuration.
 
355
     */
 
356
    for (i = 0; i < computer.num_screens; i++) {
 
357
        XtDestroyWidget(computer.screens[i]->widget);
 
358
        XtFree((XtPointer)computer.screens[i]);
 
359
    }
 
360
    XtFree((XtPointer)computer.screens);
 
361
    computer.screens = NULL;
 
362
    computer.num_screens = 0;
 
363
 
 
364
    for (i = 0; i < computer.num_devices; i++) {
 
365
        XtDestroyWidget(computer.devices[i]->widget);
 
366
        XtFree((XtPointer)computer.devices[i]);
 
367
    }
 
368
    XtFree((XtPointer)computer.devices);
 
369
    computer.devices = NULL;
 
370
    computer.num_devices = 0;
 
371
 
 
372
    for (i = 0; i < computer.num_layouts; i++) {
 
373
        XtFree((XtPointer)computer.layouts[i]->position);
 
374
        XtFree((XtPointer)computer.layouts[i]);
 
375
    }
 
376
    XtFree((XtPointer)computer.layouts);
 
377
    computer.layouts = NULL;
 
378
    computer.num_layouts = 0;
 
379
 
 
380
    for (i = 0; i < computer.num_vidmodes; i++)
 
381
        XtFree((XtPointer)computer.vidmodes[i]);
 
382
    XtFree((XtPointer)computer.vidmodes);
 
383
    computer.vidmodes = NULL;
 
384
    computer.num_vidmodes = 0;
 
385
 
 
386
    /* Reinitialize devices/screens */
 
387
    InitializeDevices();
 
388
    UpdateMenuDeviceList(MOUSE);
 
389
    UpdateMenuDeviceList(KEYBOARD);
 
390
    UpdateMenuDeviceList(CARD);
 
391
    UpdateMenuDeviceList(MONITOR);
 
392
 
 
393
    /* Update layout menu */
 
394
        /* first entry is "New server layout" */
 
395
    for (i = 1; i < ((CompositeWidget)layoutp)->composite.num_children; i++)
 
396
        XtDestroyWidget(((CompositeWidget)layoutp)->composite.children[i]);
 
397
    for (i = 0; i < layoutp->core.num_popups; i++)
 
398
        XtDestroyWidget(layoutp->core.popup_list[i]);
 
399
    lay = XF86Config->conf_layout_lst;
 
400
    while (lay != NULL) {
 
401
        sme = XtVaCreateManagedWidget("sme", smeBSBObjectClass,
 
402
                                      layoutp,
 
403
                                      XtNlabel, lay->lay_identifier,
 
404
                                      XtNmenuName, lay->lay_identifier,
 
405
                                      XtNleftBitmap, menuPixmap,
 
406
                                      NULL);
 
407
        XtAddCallback(sme, XtNcallback, SelectLayoutCallback, (XtPointer)lay);
 
408
        if (layoutsme == NULL)
 
409
            layoutsme = sme;
 
410
        layopt = XtCreatePopupShell(lay->lay_identifier, simpleMenuWidgetClass,
 
411
                                    layoutp, NULL, 0);
 
412
        sme = XtCreateManagedWidget("default", smeBSBObjectClass,
 
413
                                    layopt, NULL, 0);
 
414
        XtAddCallback(sme, XtNcallback, DefaultLayoutCallback, NULL);
 
415
        sme = XtCreateManagedWidget("remove", smeBSBObjectClass,
 
416
                                    layopt, NULL, 0);
 
417
        XtAddCallback(sme, XtNcallback, RemoveLayoutCallback, NULL);
 
418
        XtRealizeWidget(layopt);
 
419
 
 
420
        lay = (XF86ConfLayoutPtr)(lay->list.next);
 
421
    }
 
422
    computer.layout = NULL;
 
423
    SelectLayoutCallback(layoutsme,
 
424
                         XF86Config->conf_layout_lst, NULL);
 
425
 
 
426
 
 
427
    if (XF86Config->conf_flags && XF86Config->conf_flags->flg_option_lst)
 
428
        SetTip(&cpu_device);
 
429
    for (i = 0; i < computer.num_devices; i++)
 
430
        SetTip(computer.devices[i]);
 
431
 
 
432
    /* Reinitialize vidmodes */
 
433
    InitializeVidmodes();
 
434
 
 
435
    if (save_config_mode != CONFIG_LAYOUT)
 
436
        SetConfigModeCallback(topMenu, (XtPointer)(long)save_config_mode, NULL);
 
437
}
 
438
 
 
439
/*ARGSUSED*/
 
440
void
 
441
ExpertCloseAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
 
442
{
 
443
    ExpertConfigureEnd();
 
444
}
 
445
 
 
446
/*ARGSUSED*/
 
447
void
 
448
ExpertCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
449
{
 
450
    ExpertConfigureStart();
 
451
}
 
452
 
 
453
/*ARGSUSED*/
 
454
static void
 
455
PopdownCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
456
{
 
457
    ExpertConfigureEnd();
 
458
}
 
459
 
 
460
/* Files */
 
461
static void
 
462
CreateFiles(TreeNode *files)
 
463
{
 
464
    XF86ConfFilesPtr file = XF86Config->conf_files;
 
465
    TreeNode *node, *fontpath, *modulepath;
 
466
    Widget w;
 
467
    char *value;
 
468
 
 
469
    value = file->file_logfile ? file->file_logfile : "";
 
470
    node = NewNode(files, NULL, NULL, files->node, 
 
471
                   (TreeData*)XtCalloc(1, sizeof(TreeData)));
 
472
    CreateFilesField(node, "LogFile", value);
 
473
    files->child = node;
 
474
    files->update = UpdateFiles;
 
475
 
 
476
    if (XF86RGB_path)
 
477
        value = XF86RGB_path;
 
478
    else
 
479
        value = file->file_rgbpath ? file->file_rgbpath : "";
 
480
    node->next = NewNode(files, NULL, NULL, files->node,
 
481
                         (TreeData*)XtCalloc(1, sizeof(TreeData)));
 
482
    node = node->next;
 
483
    CreateFilesField(node, "RgbPath", value);
 
484
 
 
485
    w = XtVaCreateManagedWidget("ModulePath", toggleWidgetClass, tree,
 
486
                                XtNtreeParent, files->node, NULL);
 
487
    node->next = modulepath = NewNode(files, w, w, files->node, NULL);
 
488
    node = node->next;
 
489
    CreateModulePath(modulepath, NULL);
 
490
 
 
491
    w = XtVaCreateManagedWidget("FontPath", toggleWidgetClass, tree,
 
492
                                XtNtreeParent, files->node, NULL);
 
493
    node->next = fontpath = NewNode(files, w, w, files->node, NULL);
 
494
    node = node->next;
 
495
    CreateFontPath(fontpath, NULL);
 
496
}
 
497
 
 
498
static void
 
499
CreateFilesField(TreeNode *node, char *name, char *value)
 
500
{
 
501
    Widget box, text;
 
502
 
 
503
    box = XtVaCreateManagedWidget(name, boxWidgetClass, tree,
 
504
                                  XtNtreeParent, node->node, NULL);
 
505
    node->node = box;
 
506
    (void) XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
507
                                    XtNlabel, name, NULL);
 
508
    text = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
509
                                   XtNeditType, XawtextEdit, XtNstring, value,
 
510
                                   NULL);
 
511
    node->data->files.text = text;
 
512
}
 
513
 
 
514
static void
 
515
UpdateFiles(TreeNode *files)
 
516
{
 
517
    char *str;
 
518
 
 
519
    /* LogFile */
 
520
    files = files->child;
 
521
    XtVaGetValues(files->data->files.text, XtNstring, &str, NULL);
 
522
    XtFree(XF86Config->conf_files->file_logfile);
 
523
    if (*str)
 
524
        XF86Config->conf_files->file_logfile = XtNewString(str);
 
525
    else
 
526
        XF86Config->conf_files->file_logfile = NULL;
 
527
 
 
528
    /* LogFile */
 
529
    files = files->next;
 
530
    XtVaGetValues(files->data->files.text, XtNstring, &str, NULL);
 
531
    XtFree(XF86Config->conf_files->file_rgbpath);
 
532
    if (*str)
 
533
        XF86Config->conf_files->file_rgbpath = XtNewString(str);
 
534
    else
 
535
        XF86Config->conf_files->file_rgbpath = NULL;
 
536
}
 
537
 
 
538
/* FontPath */
 
539
/* Don't need to set the update tree field, as it is already set
 
540
 * as the destroy field */
 
541
static void
 
542
CreateFontPath(TreeNode *fontpath, char *path)
 
543
{
 
544
    TreeNode *prev = NULL, *node;
 
545
 
 
546
    if (path == NULL) {
 
547
        if (XF86Font_path) {
 
548
            path = XtNewString(XF86Font_path);
 
549
            if (XF86Config->conf_files && XF86Config->conf_files->file_fontpath) {
 
550
                XtFree(XF86Config->conf_files->file_fontpath);
 
551
                XF86Config->conf_files->file_fontpath = XtNewString(path);
 
552
            }
 
553
        }
 
554
        else if (XF86Config->conf_files && XF86Config->conf_files->file_fontpath)
 
555
            path = XtNewString(XF86Config->conf_files->file_fontpath);
 
556
    }
 
557
    else {
 
558
        path = XtNewString(path);
 
559
        if ((prev = fontpath->child) != NULL)
 
560
            while (prev->next)
 
561
                prev = prev->next;
 
562
    }
 
563
 
 
564
    if (path) {
 
565
        char *s;
 
566
 
 
567
        for (s = strtok(path, ","); s != NULL; s = strtok(NULL, ",")) {
 
568
            node = NewNode(fontpath, NULL, NULL, fontpath->node, NULL);
 
569
            node->destroy = FontPathChanged;
 
570
            (void) CreateFontPathField(node, s, False);
 
571
            if (fontpath->child == NULL)
 
572
                fontpath->child = node;
 
573
            else
 
574
                prev->next = node;
 
575
            prev = node;
 
576
        }
 
577
        XtFree(path);
 
578
    }
 
579
 
 
580
    node = NewNode(fontpath, NULL, NULL, fontpath->node, NULL);
 
581
    (void) CreateFontPathField(node, "", True);
 
582
    if (fontpath->child == NULL)
 
583
        fontpath->child = node;
 
584
    else
 
585
        prev->next = node;
 
586
}
 
587
 
 
588
static Widget
 
589
CreateFontPathField(TreeNode *fontpath, char *value, Bool addnew)
 
590
{
 
591
    Widget box, command, text;
 
592
    TreeData *data;
 
593
 
 
594
    box = XtVaCreateWidget("fontpath", formWidgetClass, tree,
 
595
                           XtNtreeParent, fontpath->treeParent, NULL);
 
596
    fontpath->node = box;
 
597
    if (!addnew) {
 
598
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
599
                                        NULL, 0);
 
600
        XtAddCallback(command, XtNcallback, DestroyCallback,
 
601
                      (XtPointer)fontpath);
 
602
        command = XtCreateManagedWidget("up", commandWidgetClass, box, NULL, 0);
 
603
        XtAddCallback(command, XtNcallback, FontPathCallback,
 
604
                      (XtPointer)fontpath);
 
605
        command = XtCreateManagedWidget("down", commandWidgetClass, box, NULL, 0);
 
606
        XtAddCallback(command, XtNcallback, FontPathCallback,
 
607
                      (XtPointer)fontpath);
 
608
        text = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
609
                                       XtNeditType, XawtextEdit,
 
610
                                       XtNstring, value, NULL);
 
611
    }
 
612
    else {
 
613
        command = XtCreateManagedWidget("new", commandWidgetClass, box, NULL, 0);
 
614
        XtAddCallback(command, XtNcallback, NewFontPathCallback, 
 
615
                      (XtPointer)fontpath);
 
616
        text = XtVaCreateManagedWidget("valueNew", asciiTextWidgetClass, box,
 
617
                                       XtNeditType, XawtextEdit,
 
618
                                       XtNstring, value, NULL);
 
619
    }
 
620
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
621
    data->files.text = text;
 
622
    fontpath->data = data;
 
623
 
 
624
    if (fontpath->treeParent && XtIsRealized(fontpath->treeParent))
 
625
        XtRealizeWidget(box);
 
626
    XtManageChild(box);
 
627
 
 
628
    return (box);
 
629
}
 
630
 
 
631
static void
 
632
FontPathChanged(TreeNode *node)
 
633
{
 
634
    TreeNode *parent = node->parent;
 
635
    char *fontpath = NULL, *str;
 
636
    Arg args[1];
 
637
    int pos = 0, len;
 
638
 
 
639
    /* last node is the "new" */
 
640
    for (node = parent->child; node->next != NULL; node = node->next) {
 
641
        if (pos)
 
642
            fontpath[pos++] = ',';
 
643
        XtSetArg(args[0], XtNstring, &str);
 
644
        XtGetValues(node->data->files.text, args, 1);
 
645
        len = strlen(str) + 2;
 
646
        fontpath = XtRealloc(fontpath, pos + len);
 
647
        strcpy(fontpath + pos, str);
 
648
        pos += len - 2;
 
649
    }
 
650
 
 
651
    if (XF86Config->conf_files->file_fontpath)
 
652
        XtFree(XF86Config->conf_files->file_fontpath);
 
653
    XF86Config->conf_files->file_fontpath = fontpath;
 
654
}
 
655
 
 
656
static void
 
657
NewFontPathCallback(Widget unused, XtPointer user_data, XtPointer call_data)
 
658
{
 
659
    TreeNode *fontpath, *node = (TreeNode*)user_data;
 
660
    Arg args[1];
 
661
    char *str;
 
662
 
 
663
    XtSetArg(args[0], XtNstring, &str);
 
664
    XtGetValues(node->data->files.text, args, 1);
 
665
    if (*str == '\0')
 
666
        return;
 
667
 
 
668
    fontpath = node->parent;
 
669
    DeleteNode(node);
 
670
    CreateFontPath(fontpath, str);
 
671
 
 
672
    FontPathChanged(fontpath->child);
 
673
    RelayoutTree();
 
674
}
 
675
 
 
676
/*ARGSUSED*/
 
677
static void
 
678
FontPathCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
679
{
 
680
    TreeNode *parent, *node, *fontpath = (TreeNode*)user_data;
 
681
    char *t1, *t2;
 
682
    Widget w1, w2;
 
683
 
 
684
    parent = fontpath->parent;
 
685
    node = parent->child;
 
686
    if (!node->next->next)
 
687
        return;
 
688
    if (strcmp(XtName(w), "up") == 0) {
 
689
        if (node == fontpath)
 
690
            while (node->next->next)
 
691
                node = node->next;
 
692
        else
 
693
            while (node && node->next != fontpath)
 
694
                node = node->next;
 
695
    }
 
696
    else {
 
697
        if (fontpath->next->next)
 
698
            node = fontpath->next;
 
699
        /* else is already correct */
 
700
    }
 
701
 
 
702
    w1 = node->data->files.text;
 
703
    w2 = fontpath->data->files.text;
 
704
 
 
705
    XtVaGetValues(w1, XtNstring, &t1, NULL);
 
706
    XtVaGetValues(w2, XtNstring, &t2, NULL);
 
707
    t1 = XtNewString(t1);
 
708
    XtVaSetValues(w1, XtNstring, t2, NULL);
 
709
    XtVaSetValues(w2, XtNstring, t1, NULL);
 
710
    XtFree(t1);
 
711
}
 
712
 
 
713
 
 
714
/* ModulePath */
 
715
/* Don't need to set the update tree field, as it is already set
 
716
 * as the destroy field */
 
717
static void
 
718
CreateModulePath(TreeNode *modulepath, char *path)
 
719
{
 
720
    TreeNode *prev = NULL, *node;
 
721
 
 
722
    if (path == NULL) {
 
723
        if (XF86Module_path) {
 
724
            path = XtNewString(XF86Module_path);
 
725
            if (XF86Config->conf_files && XF86Config->conf_files->file_modulepath) {
 
726
                XtFree(XF86Config->conf_files->file_modulepath);
 
727
                XF86Config->conf_files->file_modulepath = XtNewString(path);
 
728
            }
 
729
        }
 
730
        else if (XF86Config->conf_files && XF86Config->conf_files->file_modulepath)
 
731
            path = XtNewString(XF86Config->conf_files->file_modulepath);
 
732
    }
 
733
    else {
 
734
        path = XtNewString(path);
 
735
        if ((prev = modulepath->child) != NULL)
 
736
            while (prev->next)
 
737
                prev = prev->next;
 
738
    }
 
739
 
 
740
    if (path) {
 
741
        char *s;
 
742
 
 
743
        for (s = strtok(path, ","); s != NULL; s = strtok(NULL, ",")) {
 
744
            node = NewNode(modulepath, NULL, NULL, modulepath->node, NULL);
 
745
            node->destroy = ModulePathChanged;
 
746
            (void) CreateModulePathField(node, s, False);
 
747
            if (modulepath->child == NULL)
 
748
                modulepath->child = node;
 
749
            else
 
750
                prev->next = node;
 
751
            prev = node;
 
752
        }
 
753
        XtFree(path);
 
754
    }
 
755
 
 
756
    node = NewNode(modulepath, NULL, NULL, modulepath->node, NULL);
 
757
    (void) CreateModulePathField(node, "", True);
 
758
    if (modulepath->child == NULL)
 
759
        modulepath->child = node;
 
760
    else
 
761
        prev->next = node;
 
762
}
 
763
 
 
764
static Widget
 
765
CreateModulePathField(TreeNode *modulepath, char *value, Bool addnew)
 
766
{
 
767
    Widget box, command, text;
 
768
    TreeData *data;
 
769
 
 
770
    box = XtVaCreateWidget("modulepath", formWidgetClass, tree,
 
771
                           XtNtreeParent, modulepath->treeParent, NULL);
 
772
    modulepath->node = box;
 
773
    if (!addnew) {
 
774
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
775
                                        NULL, 0);
 
776
        XtAddCallback(command, XtNcallback, DestroyCallback,
 
777
                      (XtPointer)modulepath);
 
778
        text = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
779
                                       XtNeditType, XawtextEdit,
 
780
                                       XtNstring, value, NULL);
 
781
    }
 
782
    else {
 
783
        command = XtCreateManagedWidget("new", commandWidgetClass, box, NULL, 0);
 
784
        XtAddCallback(command, XtNcallback, NewModulePathCallback, 
 
785
                      (XtPointer)modulepath);
 
786
        text = XtVaCreateManagedWidget("valueNew", asciiTextWidgetClass, box,
 
787
                                       XtNeditType, XawtextEdit,
 
788
                                       XtNstring, value, NULL);
 
789
    }
 
790
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
791
    data->files.text = text;
 
792
    modulepath->data = data;
 
793
 
 
794
    if (modulepath->treeParent && XtIsRealized(modulepath->treeParent))
 
795
        XtRealizeWidget(box);
 
796
    XtManageChild(box);
 
797
 
 
798
    return (box);
 
799
}
 
800
 
 
801
static void
 
802
ModulePathChanged(TreeNode *node)
 
803
{
 
804
    TreeNode *parent = node->parent;
 
805
    char *modulepath = NULL, *str;
 
806
    Arg args[1];
 
807
    int pos = 0, len;
 
808
 
 
809
    /* last node is the "new" */
 
810
    for (node = parent->child; node->next != NULL; node = node->next) {
 
811
        if (pos)
 
812
            modulepath[pos++] = ',';
 
813
        XtSetArg(args[0], XtNstring, &str);
 
814
        XtGetValues(node->data->files.text, args, 1);
 
815
        len = strlen(str) + 2;
 
816
        modulepath = XtRealloc(modulepath, pos + len);
 
817
        strcpy(modulepath + pos, str);
 
818
        pos += len - 2;
 
819
    }
 
820
 
 
821
    if (XF86Config->conf_files->file_modulepath)
 
822
        XtFree(XF86Config->conf_files->file_modulepath);
 
823
    XF86Config->conf_files->file_modulepath = modulepath;
 
824
}
 
825
 
 
826
static void
 
827
NewModulePathCallback(Widget unused, XtPointer user_data, XtPointer call_data)
 
828
{
 
829
    TreeNode *modulepath, *node = (TreeNode*)user_data;
 
830
    Arg args[1];
 
831
    char *str;
 
832
 
 
833
    XtSetArg(args[0], XtNstring, &str);
 
834
    XtGetValues(node->data->files.text, args, 1);
 
835
    if (*str == '\0')
 
836
        return;
 
837
 
 
838
    modulepath = node->parent;
 
839
    DeleteNode(node);
 
840
    CreateModulePath(modulepath, str);
 
841
 
 
842
    ModulePathChanged(modulepath->child);
 
843
    RelayoutTree();
 
844
}
 
845
 
 
846
/* Module */
 
847
static void
 
848
CreateModule(TreeNode *module, XF86LoadPtr load)
 
849
{
 
850
    TreeNode *prev, *node;
 
851
    TreeData *data;
 
852
 
 
853
    if ((prev = module->child) != NULL)
 
854
        while (prev->next)
 
855
            prev = prev->next;
 
856
 
 
857
    while (load) {
 
858
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
859
        data->module.load = load;
 
860
        node = NewNode(module, NULL, NULL, module->node, data);
 
861
        node->destroy = ModuleDestroy;
 
862
        CreateModuleField(node, False);
 
863
        if (module->child == NULL)
 
864
            module->child = node;
 
865
        else
 
866
            prev->next = node;
 
867
        prev = node;
 
868
        load = (XF86LoadPtr)(load->list.next);
 
869
    }
 
870
 
 
871
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
872
    node = NewNode(module, NULL, NULL, module->node, data);
 
873
    CreateModuleField(node, True);
 
874
    if (module->child == NULL)
 
875
        module->child = node;
 
876
    else
 
877
        prev->next = node;
 
878
}
 
879
 
 
880
static void
 
881
CreateModuleField(TreeNode *node, Bool addnew)
 
882
{
 
883
    Widget box, command, label;
 
884
 
 
885
    box = XtVaCreateWidget("module", formWidgetClass, tree,
 
886
                           XtNtreeParent, node->treeParent, NULL);
 
887
    node->node = box;
 
888
 
 
889
    if (!addnew) {
 
890
        XF86OptionPtr *options;
 
891
        XF86LoadPtr load = node->data->module.load;
 
892
 
 
893
        options = &(load->load_opt);
 
894
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
895
                                        NULL, 0);
 
896
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
897
        command = XtCreateManagedWidget("options", commandWidgetClass, box,
 
898
                                        NULL, 0);
 
899
        XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
 
900
        label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
901
                                        XtNlabel, load->load_name, NULL);
 
902
    }
 
903
    else {
 
904
        command = XtCreateManagedWidget("new", commandWidgetClass, box,
 
905
                                        NULL, 0);
 
906
        XtAddCallback(command, XtNcallback, NewModuleCallback, (XtPointer)node);
 
907
        label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
908
                                        XtNeditType, XawtextEdit,
 
909
                                        NULL);
 
910
        node->data->module.text = label;
 
911
    }
 
912
    if (XtIsRealized(node->treeParent))
 
913
        XtRealizeWidget(box);
 
914
    XtManageChild(box);
 
915
}
 
916
 
 
917
/*ARGUSED*/
 
918
static void
 
919
ModuleDestroy(TreeNode *node)
 
920
{
 
921
    if (node->data->module.load)
 
922
        xf86removeModule(XF86Config, node->data->module.load);
 
923
}
 
924
 
 
925
/*ARGSUSED*/
 
926
static void
 
927
NewModuleCallback(Widget unused, XtPointer user_data, XtPointer call_data)
 
928
{
 
929
    TreeNode *module, *node = (TreeNode*)user_data;
 
930
    XF86LoadPtr load;
 
931
    Arg args[1];
 
932
    char *label;
 
933
 
 
934
    XtSetArg(args[0], XtNstring, &label);
 
935
    XtGetValues(node->data->module.text, args, 1);
 
936
    if (*label == '\0')
 
937
        return;
 
938
 
 
939
    module = node->parent;
 
940
    DeleteNode(node);
 
941
    load = (XF86LoadPtr)XtCalloc(1, sizeof(XF86LoadRec));
 
942
    load->load_name = XtNewString(label);
 
943
    XF86Config->conf_modules->mod_load_lst =
 
944
        xf86addModule(XF86Config->conf_modules->mod_load_lst, load);
 
945
 
 
946
    CreateModule(module, load);
 
947
    RelayoutTree();
 
948
}
 
949
 
 
950
/* Modes */
 
951
static void
 
952
CreateModes(TreeNode *parent, XF86ConfModesPtr modes)
 
953
{
 
954
    TreeNode *node, *prev;
 
955
    TreeData *data;
 
956
 
 
957
    if ((prev = parent->child) != NULL)
 
958
        while (prev->next)
 
959
            prev = prev->next;
 
960
 
 
961
    while (modes) {
 
962
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
963
        data->modes.modes = modes;
 
964
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
965
        node->destroy = ModesDestroy;
 
966
        CreateModesField(node, False);
 
967
        if (parent->child == NULL)
 
968
            parent->child = node;
 
969
        else
 
970
            prev->next = node;
 
971
        prev = node;
 
972
 
 
973
        modes = (XF86ConfModesPtr)(modes->list.next);
 
974
    }
 
975
 
 
976
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
977
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
978
    CreateModesField(node, True);
 
979
    if (parent->child == NULL)
 
980
        parent->child = node;
 
981
    else
 
982
        prev->next = node;
 
983
}
 
984
 
 
985
static void
 
986
CreateModesField(TreeNode *node, Bool addnew)
 
987
{
 
988
    Widget box, command, label;
 
989
 
 
990
    box = XtVaCreateWidget("modes", formWidgetClass, tree,
 
991
                           XtNtreeParent, node->treeParent, NULL);
 
992
    node->node = box;
 
993
 
 
994
    if (!addnew) {
 
995
        XF86ConfModesPtr modes = node->data->modes.modes;
 
996
 
 
997
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
998
                                        NULL, 0);
 
999
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
1000
        label = XtVaCreateManagedWidget("mode", toggleWidgetClass, box,
 
1001
                                        XtNlabel, modes->modes_identifier,
 
1002
                                        XtNstate, True,
 
1003
                                        NULL);
 
1004
        node->toggle = label;
 
1005
        XtAddCallback(label, XtNcallback, ToggleCallback, (XtPointer)node);
 
1006
        CreateModesModeLine(node, node->data->modes.modes->mon_modeline_lst);
 
1007
    }
 
1008
    else {
 
1009
        command = XtCreateManagedWidget("new", commandWidgetClass, box,
 
1010
                                        NULL, 0);
 
1011
        XtAddCallback(command, XtNcallback, NewModesCallback, (XtPointer)node);
 
1012
        label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
1013
                                        XtNeditType, XawtextEdit,
 
1014
                                        NULL);
 
1015
        node->data->modes.text = label;
 
1016
    }
 
1017
    if (XtIsRealized(node->treeParent))
 
1018
        XtRealizeWidget(box);
 
1019
    XtManageChild(box);
 
1020
}
 
1021
 
 
1022
/*ARGUSED*/
 
1023
static void
 
1024
ModesDestroy(TreeNode *node)
 
1025
{
 
1026
    if (node->data->modes.modes) {
 
1027
        int i;
 
1028
        TreeNode *mon = monitorTree->child;
 
1029
 
 
1030
        /* last one is the "new" entry */
 
1031
        while (mon && mon->next) {
 
1032
            /* UseModes is the second entry */
 
1033
            TreeNode *mod = mon->child->next->child;
 
1034
            CompositeWidget composite;
 
1035
 
 
1036
            while (mod && mod->next) {
 
1037
                TreeNode *next = mod->next;
 
1038
 
 
1039
                if (mod && strcmp(mod->data->modeslink.modeslink->ml_modes_str,
 
1040
                                  node->data->modes.modes->modes_identifier) == 0)
 
1041
                    /* Needs to do string comparison because may be deleting
 
1042
                     * a "test" Modes section, with no Modelines.
 
1043
                     */
 
1044
                    DeleteNode(mod);
 
1045
                mod = next;
 
1046
            }
 
1047
            composite = (CompositeWidget)mod->data->modeslink.menu;
 
1048
 
 
1049
            for (i = 0; i < composite->composite.num_children; ++i)
 
1050
                if (strcmp(XtName(composite->composite.children[i]),
 
1051
                           node->data->modes.modes->modes_identifier) == 0)
 
1052
                    XtDestroyWidget(composite->composite.children[i]);
 
1053
 
 
1054
            mon = mon->next;
 
1055
        }
 
1056
 
 
1057
        xf86removeModes(XF86Config, node->data->modes.modes);
 
1058
    }
 
1059
}
 
1060
 
 
1061
/*ARGSUSED*/
 
1062
static void
 
1063
NewModesCallback(Widget unused, XtPointer user_data, XtPointer call_data)
 
1064
{
 
1065
    TreeNode *parent, *node = (TreeNode*)user_data;
 
1066
    XF86ConfModesPtr modes;
 
1067
    Arg args[1];
 
1068
    char *label;
 
1069
 
 
1070
    XtSetArg(args[0], XtNstring, &label);
 
1071
    XtGetValues(node->data->modes.text, args, 1);
 
1072
    if (*label == '\0')
 
1073
        return;
 
1074
 
 
1075
    parent = node->parent;
 
1076
    DeleteNode(node);
 
1077
    modes = (XF86ConfModesPtr)XtCalloc(1, sizeof(XF86ConfModesRec));
 
1078
    modes->modes_identifier = XtNewString(label);
 
1079
    XF86Config->conf_modes_lst =
 
1080
        xf86addModes(XF86Config->conf_modes_lst, modes);
 
1081
 
 
1082
    {
 
1083
        TreeNode *mon = monitorTree->child;
 
1084
        Widget sme;
 
1085
 
 
1086
        /* last one is the "new" entry */
 
1087
        while (mon && mon->next) {
 
1088
            /* UseModes is the second entry */
 
1089
            TreeNode *mod = mon->child->next->child;
 
1090
 
 
1091
            while (mod && mod->next)
 
1092
                mod = mod->next;
 
1093
 
 
1094
            sme = XtCreateManagedWidget(modes->modes_identifier,
 
1095
                                        smeBSBObjectClass,
 
1096
                                        mod->data->modeslink.menu, NULL, 0);
 
1097
            XtAddCallback(sme, XtNcallback, NewMonitorModesCallback,
 
1098
                          (XtPointer)mod);
 
1099
 
 
1100
            mon = mon->next;
 
1101
        }
 
1102
    }
 
1103
 
 
1104
    CreateModes(parent, modes);
 
1105
    RelayoutTree();
 
1106
}
 
1107
 
 
1108
static void
 
1109
CreateModesModeLine(TreeNode *parent, XF86ConfModeLinePtr modeline)
 
1110
{
 
1111
    TreeNode *node, *prev;
 
1112
    TreeData *data;
 
1113
 
 
1114
    if ((prev = parent->child) != NULL)
 
1115
        while (prev->next)
 
1116
            prev = prev->next;
 
1117
 
 
1118
    while (modeline) {
 
1119
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
1120
        data->modeline.modeline = modeline;
 
1121
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
1122
        node->destroy = ModesModeLineDestroy;
 
1123
        CreateModeLineField(node, False, False);
 
1124
        if (parent->child == NULL)
 
1125
            parent->child = node;
 
1126
        else
 
1127
            prev->next = node;
 
1128
        prev = node;
 
1129
        modeline = (XF86ConfModeLinePtr)(modeline->list.next);
 
1130
    }
 
1131
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
1132
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
1133
    if (parent->child == NULL)
 
1134
        parent->child = node;
 
1135
    else
 
1136
        prev->next = node;
 
1137
    prev = node;
 
1138
    CreateModeLineField(node, True, False);
 
1139
}
 
1140
 
 
1141
/* This function should allow creating modelines for the
 
1142
   Mode and Monitor section */
 
1143
static void
 
1144
CreateModeLineField(TreeNode *node, Bool addnew, Bool monitor)
 
1145
{
 
1146
    Widget box, command;
 
1147
    char buf[512], tmp[32];
 
1148
 
 
1149
    box = XtVaCreateWidget("modeline", formWidgetClass, tree,
 
1150
                           XtNtreeParent, node->treeParent, NULL);
 
1151
    node->node = box;
 
1152
 
 
1153
    if (!addnew) {
 
1154
        XF86ConfModeLinePtr mod = node->data->modeline.modeline;
 
1155
 
 
1156
        command = XtCreateManagedWidget("remove", commandWidgetClass,
 
1157
                                        box, NULL, 0);
 
1158
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
1159
        XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
1160
                                XtNlabel, mod->ml_identifier, NULL);
 
1161
 
 
1162
        XmuSnprintf(buf, sizeof(buf), "%g %d %d %d %d %d %d %d %d",
 
1163
            mod->ml_clock / 1000., mod->ml_hdisplay, mod->ml_hsyncstart,
 
1164
            mod->ml_hsyncend, mod->ml_htotal, mod->ml_vdisplay,
 
1165
            mod->ml_vsyncstart, mod->ml_vsyncend, mod->ml_vtotal);
 
1166
        if (mod->ml_flags & XF86CONF_INTERLACE)
 
1167
            strcat(buf, " interlace");
 
1168
        if (mod->ml_flags & XF86CONF_PHSYNC)
 
1169
            strcat(buf, " +hsync");
 
1170
        if (mod->ml_flags & XF86CONF_NHSYNC)
 
1171
            strcat(buf, " -hsync");
 
1172
        if (mod->ml_flags & XF86CONF_PVSYNC)
 
1173
            strcat(buf, " +vsync");
 
1174
        if (mod->ml_flags & XF86CONF_NVSYNC)
 
1175
            strcat(buf, " -vsync");
 
1176
        if (mod->ml_flags & XF86CONF_CSYNC)
 
1177
            strcat(buf, " composite");
 
1178
        if (mod->ml_flags & XF86CONF_PCSYNC)
 
1179
            strcat(buf, " +csync");
 
1180
        if (mod->ml_flags & XF86CONF_NCSYNC)
 
1181
            strcat(buf, " -csync");
 
1182
        if (mod->ml_flags & XF86CONF_DBLSCAN)
 
1183
            strcat(buf, " doublescan");
 
1184
        if (mod->ml_flags & XF86CONF_BCAST)
 
1185
            strcat(buf, " bcast");
 
1186
        if (mod->ml_flags & XF86CONF_HSKEW) {
 
1187
            XmuSnprintf(tmp, sizeof(tmp), " hskew %d", mod->ml_hskew);
 
1188
            strcat(buf, tmp);
 
1189
        }
 
1190
        if (mod->ml_flags & XF86CONF_VSCAN) {
 
1191
            XmuSnprintf(tmp, sizeof(tmp), " vscan %d", mod->ml_vscan);
 
1192
            strcat(buf, tmp);
 
1193
        }
 
1194
        if (mod->ml_flags & XF86CONF_CUSTOM)
 
1195
            strcat(buf, " custom");
 
1196
        node->data->modeline.value =
 
1197
            XtVaCreateManagedWidget("modeline", asciiTextWidgetClass, box,
 
1198
                                    XtNeditType, XawtextEdit,
 
1199
                                    XtNstring, buf, NULL);
 
1200
    }
 
1201
    else {
 
1202
        *buf = '\0';
 
1203
        command = XtCreateManagedWidget("new", commandWidgetClass,
 
1204
                                        box, NULL, 0);
 
1205
        XtAddCallback(command, XtNcallback, monitor ?
 
1206
                      NewMonitorModeLineCallback : NewModesModeLineCallback,
 
1207
                      (XtPointer)node);
 
1208
        node->data->modeline.text =
 
1209
                XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
1210
                                        XtNeditType, XawtextEdit, NULL);
 
1211
        node->data->modeline.value =
 
1212
                XtVaCreateManagedWidget("modelineNew", asciiTextWidgetClass, box,
 
1213
                                        XtNeditType, XawtextEdit, NULL);
 
1214
    }
 
1215
    if (XtIsRealized(node->treeParent))
 
1216
        XtRealizeWidget(box);
 
1217
    XtManageChild(box);
 
1218
}
 
1219
 
 
1220
/*ARGUSED*/
 
1221
static void
 
1222
ModesModeLineDestroy(TreeNode *node)
 
1223
{
 
1224
    if (node->data->modeline.modeline)
 
1225
        xf86removeModesModeLine(node->parent->data->modes.modes,
 
1226
                                node->data->modeline.modeline);
 
1227
}
 
1228
 
 
1229
/*ARGSUSED*/
 
1230
static void
 
1231
NewModesModeLineCallback(Widget unused, XtPointer user_data, XtPointer call_data)
 
1232
{
 
1233
    TreeNode *parent, *node = (TreeNode*)user_data;
 
1234
    XF86ConfModeLinePtr modeline;
 
1235
    Arg args[1];
 
1236
    char *ident, *value;
 
1237
 
 
1238
    XtSetArg(args[0], XtNstring, &ident);
 
1239
    XtGetValues(node->data->modeline.text, args, 1);
 
1240
    XtSetArg(args[0], XtNstring, &value);
 
1241
    XtGetValues(node->data->modeline.value, args, 1);
 
1242
    if (*ident == '\0' || *value == '\0')
 
1243
        return;
 
1244
 
 
1245
    parent = node->parent;
 
1246
    DeleteNode(node);
 
1247
    modeline = ParseModeLine(ident, value);
 
1248
    parent->data->modes.modes->mon_modeline_lst =
 
1249
        xf86addModeLine(parent->data->modes.modes->mon_modeline_lst, modeline);
 
1250
 
 
1251
    CreateModesModeLine(parent, modeline);
 
1252
    RelayoutTree();
 
1253
}
 
1254
 
 
1255
static XF86ConfModeLinePtr
 
1256
ParseModeLine(char *identifier, char *modeline)
 
1257
{
 
1258
    XF86ConfModeLinePtr ml = (XF86ConfModeLinePtr)
 
1259
        XtCalloc(1, sizeof(XF86ConfModeLineRec));
 
1260
    char *s, *ptr = modeline;
 
1261
 
 
1262
    /* Identifier */
 
1263
    ml->ml_identifier = XtNewString(identifier);
 
1264
 
 
1265
    ml->ml_clock = (int)(strtod(ptr, &ptr) * 1000.0 + 0.5);
 
1266
    while (*ptr && isspace(*ptr)) ++ptr;
 
1267
 
 
1268
    ml->ml_hdisplay = strtol(ptr, &ptr, 10);
 
1269
    while (*ptr && isspace(*ptr)) ++ptr;
 
1270
 
 
1271
    ml->ml_hsyncstart = strtol(ptr, &ptr, 10);
 
1272
    while (*ptr && isspace(*ptr)) ++ptr;
 
1273
 
 
1274
    ml->ml_hsyncend = strtol(ptr, &ptr, 10);
 
1275
    while (*ptr && isspace(*ptr)) ++ptr;
 
1276
 
 
1277
    ml->ml_htotal = strtol(ptr, &ptr, 10);
 
1278
    while (*ptr && isspace(*ptr)) ++ptr;
 
1279
 
 
1280
    ml->ml_vdisplay = strtol(ptr, &ptr, 10);
 
1281
    while (*ptr && isspace(*ptr)) ++ptr;
 
1282
 
 
1283
    ml->ml_vsyncstart = strtol(ptr, &ptr, 10);
 
1284
    while (*ptr && isspace(*ptr)) ++ptr;
 
1285
 
 
1286
    ml->ml_vsyncend = strtol(ptr, &ptr, 10);
 
1287
    while (*ptr && isspace(*ptr)) ++ptr;
 
1288
 
 
1289
    ml->ml_vtotal = strtol(ptr, &ptr, 10);
 
1290
    while (*ptr && isspace(*ptr)) ++ptr;
 
1291
 
 
1292
    s = ptr;
 
1293
    while (*s) {
 
1294
        *s = tolower(*s);
 
1295
        ++s;
 
1296
    }
 
1297
    s = ptr;
 
1298
 
 
1299
    while (*ptr) {
 
1300
        while (*s && isspace(*s))
 
1301
            s++;
 
1302
        ptr = s;
 
1303
        while (*s && !isspace(*s))
 
1304
            s++;
 
1305
 
 
1306
        if (s != ptr) {
 
1307
            Bool done = *s == '\0';
 
1308
 
 
1309
            *s = '\0';
 
1310
            if (strcmp(ptr, "interlace") == 0)
 
1311
                ml->ml_flags |= XF86CONF_INTERLACE;
 
1312
            else if (strcmp(ptr, "+hsync") == 0)
 
1313
                ml->ml_flags |= XF86CONF_PHSYNC;
 
1314
            else if (strcmp(ptr, "-hsync") == 0)
 
1315
                ml->ml_flags |= XF86CONF_NHSYNC;
 
1316
            else if (strcmp(ptr, "+vsync") == 0)
 
1317
                ml->ml_flags |= XF86CONF_PVSYNC;
 
1318
            else if (strcmp(ptr, "-vsync") == 0)
 
1319
                ml->ml_flags |= XF86CONF_NVSYNC;
 
1320
            else if (strcmp(ptr, "composite") == 0)
 
1321
                ml->ml_flags |= XF86CONF_CSYNC;
 
1322
            else if (strcmp(ptr, "+csync") == 0)
 
1323
                ml->ml_flags |= XF86CONF_PCSYNC;
 
1324
            else if (strcmp(ptr, "-csync") == 0)
 
1325
                ml->ml_flags |= XF86CONF_NCSYNC;
 
1326
            else if (strcmp(ptr, "doublescan") == 0)
 
1327
                ml->ml_flags |= XF86CONF_DBLSCAN;
 
1328
            else if (strcmp(ptr, "bcast") == 0)
 
1329
                ml->ml_flags |= XF86CONF_BCAST;
 
1330
            else if (strcmp(ptr, "hskew") == 0) {
 
1331
                ++s;
 
1332
                while (*s && isspace(*s))
 
1333
                    ++s;
 
1334
                ptr = s;
 
1335
                while (*s && !isspace(*s))
 
1336
                    ++s;
 
1337
                if (ptr != s) {
 
1338
                    ml->ml_hskew = strtol(ptr, &s, 10);
 
1339
                    ml->ml_flags |= XF86CONF_HSKEW;
 
1340
                    --s;
 
1341
                }
 
1342
            }
 
1343
            else if (strcmp(ptr, "vscan") == 0) {
 
1344
                ++s;
 
1345
                while (*s && isspace(*s))
 
1346
                    ++s;
 
1347
                ptr = s;
 
1348
                while (*s && !isspace(*s))
 
1349
                    ++s;
 
1350
                if (ptr != s) {
 
1351
                    ml->ml_vscan = strtol(ptr, &s, 10);
 
1352
                    ml->ml_flags |= XF86CONF_VSCAN;
 
1353
                    --s;
 
1354
                }
 
1355
            }
 
1356
            else if (strcmp(ptr, "custom") == 0)
 
1357
                ml->ml_flags |= XF86CONF_CUSTOM;
 
1358
            ++s;
 
1359
            if (done)
 
1360
                break;
 
1361
            ptr = s;
 
1362
        }
 
1363
    }
 
1364
 
 
1365
    return (ml);
 
1366
}
 
1367
 
 
1368
/* VideoAdpator */
 
1369
static void
 
1370
CreateVideoAdaptor(TreeNode *parent, XF86ConfVideoAdaptorPtr video)
 
1371
{
 
1372
    TreeNode *node, *prev;
 
1373
    TreeData *data;
 
1374
 
 
1375
    if ((prev = parent->child) != NULL)
 
1376
        while (prev->next)
 
1377
            prev = prev->next;
 
1378
 
 
1379
    while (video) {
 
1380
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
1381
        data->video.video = video;
 
1382
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
1383
        node->destroy = VideoAdaptorDestroy;
 
1384
        node->update = VideoAdaptorUpdate;
 
1385
        CreateVideoAdaptorField(node, False);
 
1386
        if (parent->child == NULL)
 
1387
            parent->child = node;
 
1388
        else
 
1389
            prev->next = node;
 
1390
        prev = node;
 
1391
 
 
1392
        video = (XF86ConfVideoAdaptorPtr)(video->list.next);
 
1393
    }
 
1394
 
 
1395
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
1396
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
1397
    CreateVideoAdaptorField(node, True);
 
1398
    if (parent->child == NULL)
 
1399
        parent->child = node;
 
1400
    else
 
1401
        prev->next = node;
 
1402
}
 
1403
 
 
1404
static void
 
1405
CreateVideoAdaptorField(TreeNode *node, Bool addnew)
 
1406
{
 
1407
    Widget box, command, label;
 
1408
 
 
1409
    box = XtVaCreateWidget("video", formWidgetClass, tree,
 
1410
                           XtNtreeParent, node->treeParent, NULL);
 
1411
    node->node = box;
 
1412
 
 
1413
    if (!addnew) {
 
1414
        char *str;
 
1415
        TreeNode *port;
 
1416
        XF86ConfVideoAdaptorPtr video = node->data->video.video;
 
1417
 
 
1418
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
1419
                                        NULL, 0);
 
1420
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
1421
        command = XtCreateManagedWidget("options", commandWidgetClass, box,
 
1422
                                        NULL, 0);
 
1423
        XtAddCallback(command, XtNcallback, OptionsCallback,
 
1424
                      (XtPointer)&(video->va_option_lst));
 
1425
        label = XtVaCreateManagedWidget("adaptor", labelWidgetClass, box,
 
1426
                                        XtNlabel, video->va_identifier,
 
1427
                                        NULL);
 
1428
 
 
1429
        XtCreateManagedWidget("vendorL", labelWidgetClass, box, NULL, 0);
 
1430
        str = video->va_vendor ? video->va_vendor : "";
 
1431
        node->data->video.vendor =
 
1432
                XtVaCreateManagedWidget("vendor", asciiTextWidgetClass, box,
 
1433
                                        XtNeditType, XawtextEdit,
 
1434
                                        XtNstring, str,
 
1435
                                        NULL);
 
1436
 
 
1437
        XtCreateManagedWidget("boardL", labelWidgetClass, box, NULL, 0);
 
1438
        str = video->va_board ? video->va_board : "";
 
1439
        node->data->video.board =
 
1440
                XtVaCreateManagedWidget("board", asciiTextWidgetClass, box,
 
1441
                                        XtNeditType, XawtextEdit,
 
1442
                                        XtNstring, str,
 
1443
                                        NULL);
 
1444
 
 
1445
        XtCreateManagedWidget("busidL", labelWidgetClass, box, NULL, 0);
 
1446
        str = video->va_busid ? video->va_busid : "";
 
1447
        node->data->video.busid =
 
1448
                XtVaCreateManagedWidget("busid", asciiTextWidgetClass, box,
 
1449
                                        XtNeditType, XawtextEdit,
 
1450
                                        XtNstring, str,
 
1451
                                        NULL);
 
1452
 
 
1453
        XtCreateManagedWidget("driverL", labelWidgetClass, box, NULL, 0);
 
1454
        str = video->va_driver ? video->va_driver : "";
 
1455
        node->data->video.driver =
 
1456
                XtVaCreateManagedWidget("driver", asciiTextWidgetClass, box,
 
1457
                                        XtNeditType, XawtextEdit,
 
1458
                                        XtNstring, str,
 
1459
                                        NULL);
 
1460
 
 
1461
        label = XtVaCreateManagedWidget("VideoPort", toggleWidgetClass, tree,
 
1462
                                        XtNstate, True,
 
1463
                                        XtNtreeParent, box,
 
1464
                                        NULL);
 
1465
        port = NewNode(node, label, label, node->node, NULL);
 
1466
        node->child = port;
 
1467
        CreateVideoPort(port, video->va_port_lst);
 
1468
    }
 
1469
    else {
 
1470
        command = XtCreateManagedWidget("new", commandWidgetClass, box,
 
1471
                                        NULL, 0);
 
1472
        XtAddCallback(command, XtNcallback, NewVideoAdaptorCallback,
 
1473
                      (XtPointer)node);
 
1474
        label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
1475
                                        XtNeditType, XawtextEdit,
 
1476
                                        NULL);
 
1477
        node->data->video.text = label;
 
1478
    }
 
1479
    if (XtIsRealized(node->treeParent))
 
1480
        XtRealizeWidget(box);
 
1481
    XtManageChild(box);
 
1482
}
 
1483
 
 
1484
/*ARGUSED*/
 
1485
static void
 
1486
VideoAdaptorDestroy(TreeNode *node)
 
1487
{
 
1488
    if (node->data->video.video) {
 
1489
        int i;
 
1490
        TreeNode *scrn = screenTree->child;
 
1491
 
 
1492
        /* last one is the "new" entry */
 
1493
        while (scrn && scrn->next) {
 
1494
            /* VideoAdator is the first entry */
 
1495
            TreeNode *ad = scrn->child->child;
 
1496
            CompositeWidget composite;
 
1497
 
 
1498
            while (ad && ad->next) {
 
1499
                TreeNode *next = ad->next;
 
1500
 
 
1501
                if (ad && strcmp(ad->data->adaptorlink.adaptorlink->al_adaptor_str,
 
1502
                                  node->data->video.video->va_identifier) == 0)
 
1503
                    DeleteNode(ad);
 
1504
                ad = next;
 
1505
            }
 
1506
            composite = (CompositeWidget)ad->data->adaptorlink.menu;
 
1507
 
 
1508
            for (i = 0; i < composite->composite.num_children; ++i)
 
1509
                if (strcmp(XtName(composite->composite.children[i]),
 
1510
                           node->data->video.video->va_identifier) == 0)
 
1511
                    XtDestroyWidget(composite->composite.children[i]);
 
1512
 
 
1513
            scrn = scrn->next;
 
1514
        }
 
1515
 
 
1516
        xf86removeVideoAdaptor(XF86Config, node->data->video.video);
 
1517
    }
 
1518
}
 
1519
 
 
1520
/*ARGSUSED*/
 
1521
static void
 
1522
NewVideoAdaptorCallback(Widget unused, XtPointer user_data, XtPointer call_data)
 
1523
{
 
1524
    TreeNode *parent, *node = (TreeNode*)user_data;
 
1525
    XF86ConfVideoAdaptorPtr video;
 
1526
    Arg args[1];
 
1527
    char *label;
 
1528
 
 
1529
    XtSetArg(args[0], XtNstring, &label);
 
1530
    XtGetValues(node->data->video.text, args, 1);
 
1531
    if (*label == '\0')
 
1532
        return;
 
1533
 
 
1534
    parent = node->parent;
 
1535
    DeleteNode(node);
 
1536
    video = (XF86ConfVideoAdaptorPtr)
 
1537
        XtCalloc(1, sizeof(XF86ConfVideoAdaptorRec));
 
1538
    video->va_identifier = XtNewString(label);
 
1539
    XF86Config->conf_videoadaptor_lst =
 
1540
        xf86addVideoAdaptor(XF86Config->conf_videoadaptor_lst, video);
 
1541
 
 
1542
    {
 
1543
        TreeNode *scrn = screenTree->child;
 
1544
        Widget sme;
 
1545
 
 
1546
        /* last one is the "new" entry */
 
1547
        while (scrn && scrn->next) {
 
1548
            /* VideoAdaptor is the first entry */
 
1549
            TreeNode *ad = scrn->child->child;
 
1550
 
 
1551
            while (ad && ad->next)
 
1552
                ad = ad->next;
 
1553
 
 
1554
            sme = XtCreateManagedWidget(video->va_identifier,
 
1555
                                        smeBSBObjectClass,
 
1556
                                        ad->data->adaptorlink.menu, NULL, 0);
 
1557
            XtAddCallback(sme, XtNcallback, NewScreenAdaptorCallback,
 
1558
                          (XtPointer)ad);
 
1559
 
 
1560
            scrn = scrn->next;
 
1561
        }
 
1562
    }
 
1563
 
 
1564
    CreateVideoAdaptor(parent, video);
 
1565
    RelayoutTree();
 
1566
}
 
1567
 
 
1568
static void
 
1569
VideoAdaptorUpdate(TreeNode *node)
 
1570
{
 
1571
    char *str;
 
1572
 
 
1573
    /* vendor */
 
1574
    XtVaGetValues(node->data->video.vendor, XtNstring, &str, NULL);
 
1575
    XtFree(node->data->video.video->va_vendor);
 
1576
    if (*str)
 
1577
        node->data->video.video->va_vendor = XtNewString(str);
 
1578
    else
 
1579
        node->data->video.video->va_vendor = NULL;
 
1580
 
 
1581
    /* board */
 
1582
    XtVaGetValues(node->data->video.board, XtNstring, &str, NULL);
 
1583
    XtFree(node->data->video.video->va_board);
 
1584
    if (*str)
 
1585
        node->data->video.video->va_board = XtNewString(str);
 
1586
    else
 
1587
        node->data->video.video->va_board = NULL;
 
1588
 
 
1589
    /* busid */
 
1590
    XtVaGetValues(node->data->video.busid, XtNstring, &str, NULL);
 
1591
    XtFree(node->data->video.video->va_busid);
 
1592
    if (*str)
 
1593
        node->data->video.video->va_busid = XtNewString(str);
 
1594
    else
 
1595
        node->data->video.video->va_busid = NULL;
 
1596
 
 
1597
    /* driver */
 
1598
    XtVaGetValues(node->data->video.driver, XtNstring, &str, NULL);
 
1599
    XtFree(node->data->video.video->va_driver);
 
1600
    if (*str)
 
1601
        node->data->video.video->va_driver = XtNewString(str);
 
1602
    else
 
1603
        node->data->video.video->va_driver = NULL;
 
1604
}
 
1605
 
 
1606
static void
 
1607
CreateVideoPort(TreeNode *parent, XF86ConfVideoPortPtr port)
 
1608
{
 
1609
    TreeNode *prev, *node;
 
1610
    TreeData *data;
 
1611
 
 
1612
    if ((prev = parent->child) != NULL)
 
1613
        while (prev->next)
 
1614
            prev = prev->next;
 
1615
 
 
1616
    while (port) {
 
1617
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
1618
        data->port.port = port;
 
1619
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
1620
        node->destroy = VideoPortDestroy;
 
1621
        CreateVideoPortField(node, False);
 
1622
        if (parent->child == NULL)
 
1623
            parent->child = node;
 
1624
        else
 
1625
            prev->next = node;
 
1626
        prev = node;
 
1627
        port = (XF86ConfVideoPortPtr)(port->list.next);
 
1628
    }
 
1629
 
 
1630
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
1631
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
1632
    CreateVideoPortField(node, True);
 
1633
    if (parent->child == NULL)
 
1634
        parent->child = node;
 
1635
    else
 
1636
        prev->next = node;
 
1637
}
 
1638
 
 
1639
static void
 
1640
CreateVideoPortField(TreeNode *node, Bool addnew)
 
1641
{
 
1642
    Widget box, command, label;
 
1643
 
 
1644
    box = XtVaCreateWidget("port", formWidgetClass, tree,
 
1645
                           XtNtreeParent, node->treeParent, NULL);
 
1646
    node->node = box;
 
1647
 
 
1648
    if (!addnew) {
 
1649
        XF86OptionPtr *options;
 
1650
        XF86ConfVideoPortPtr port = node->data->port.port;
 
1651
 
 
1652
        options = &(port->vp_option_lst);
 
1653
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
1654
                                        NULL, 0);
 
1655
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
1656
        command = XtCreateManagedWidget("options", commandWidgetClass, box,
 
1657
                                        NULL, 0);
 
1658
        XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
 
1659
        label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
1660
                                        XtNlabel, port->vp_identifier, NULL);
 
1661
    }
 
1662
    else {
 
1663
        command = XtCreateManagedWidget("new", commandWidgetClass, box,
 
1664
                                        NULL, 0);
 
1665
        XtAddCallback(command, XtNcallback, NewVideoPortCallback, (XtPointer)node);
 
1666
        label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
1667
                                        XtNeditType, XawtextEdit,
 
1668
                                        NULL);
 
1669
        node->data->port.text = label;
 
1670
    }
 
1671
    if (XtIsRealized(node->treeParent))
 
1672
        XtRealizeWidget(box);
 
1673
    XtManageChild(box);
 
1674
}
 
1675
 
 
1676
/*ARGUSED*/
 
1677
static void
 
1678
VideoPortDestroy(TreeNode *node)
 
1679
{
 
1680
    if (node->data->port.port)
 
1681
        xf86removeVideoPort(node->parent->parent->data->video.video,
 
1682
                            node->data->port.port);
 
1683
}
 
1684
 
 
1685
/*ARGSUSED*/
 
1686
static void
 
1687
NewVideoPortCallback(Widget unused, XtPointer user_data, XtPointer call_data)
 
1688
{
 
1689
    TreeNode *video, *node = (TreeNode*)user_data;
 
1690
    XF86ConfVideoPortPtr port;
 
1691
    Arg args[1];
 
1692
    char *label;
 
1693
 
 
1694
    XtSetArg(args[0], XtNstring, &label);
 
1695
    XtGetValues(node->data->port.text, args, 1);
 
1696
    if (*label == '\0')
 
1697
        return;
 
1698
 
 
1699
    video = node->parent->parent;
 
1700
    DeleteNode(node);
 
1701
    port = (XF86ConfVideoPortPtr)XtCalloc(1, sizeof(XF86ConfVideoPortRec));
 
1702
    port->vp_identifier = XtNewString(label);
 
1703
    video->data->video.video->va_port_lst =
 
1704
        xf86addVideoPort(video->data->video.video->va_port_lst, port);
 
1705
 
 
1706
    CreateVideoPort(video, port);
 
1707
    RelayoutTree();
 
1708
}
 
1709
 
 
1710
/* Monitor */
 
1711
static void
 
1712
CreateMonitor(TreeNode *parent, XF86ConfMonitorPtr mon)
 
1713
{
 
1714
    TreeNode *prev, *node;
 
1715
    TreeData *data;
 
1716
 
 
1717
    if ((prev = parent->child) != NULL)
 
1718
        while (prev->next)
 
1719
            prev = prev->next;
 
1720
 
 
1721
    while (mon) {
 
1722
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
1723
        data->monitor.monitor = mon;
 
1724
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
1725
        node->destroy = MonitorDestroy;
 
1726
        node->update = MonitorUpdate;
 
1727
        CreateMonitorField(node, False);
 
1728
        if (parent->child == NULL)
 
1729
            parent->child = node;
 
1730
        else
 
1731
            prev->next = node;
 
1732
        prev = node;
 
1733
        mon = (XF86ConfMonitorPtr)(mon->list.next);
 
1734
    }
 
1735
 
 
1736
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
1737
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
1738
    CreateMonitorField(node, True);
 
1739
    if (parent->child == NULL)
 
1740
        parent->child = node;
 
1741
    else
 
1742
        prev->next = node;
 
1743
}
 
1744
 
 
1745
static void
 
1746
CreateMonitorField(TreeNode *node, Bool addnew)
 
1747
{
 
1748
    Widget box, command, label;
 
1749
 
 
1750
    box = XtVaCreateWidget("monitor", formWidgetClass, tree,
 
1751
                           XtNtreeParent, node->treeParent, NULL);
 
1752
    node->node = box;
 
1753
 
 
1754
    if (!addnew) {
 
1755
        char *str, buf[256];
 
1756
        XF86OptionPtr *options;
 
1757
        XF86ConfMonitorPtr mon = node->data->monitor.monitor;
 
1758
        Widget useModes;
 
1759
        TreeNode *modeline, *modes, *prev;
 
1760
 
 
1761
        options = &(mon->mon_option_lst);
 
1762
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
1763
                                        NULL, 0);
 
1764
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
1765
        command = XtCreateManagedWidget("options", commandWidgetClass, box,
 
1766
                                        NULL, 0);
 
1767
        XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
 
1768
        label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
1769
                                        XtNlabel, mon->mon_identifier, NULL);
 
1770
 
 
1771
        XtCreateManagedWidget("vendorL", labelWidgetClass, box, NULL, 0);
 
1772
        str = mon->mon_vendor ? mon->mon_vendor : "";
 
1773
        node->data->monitor.vendor =
 
1774
                XtVaCreateManagedWidget("vendor", asciiTextWidgetClass, box,
 
1775
                                        XtNeditType, XawtextEdit,
 
1776
                                        XtNstring, str,
 
1777
                                        NULL);
 
1778
 
 
1779
        XtCreateManagedWidget("modelnameL", labelWidgetClass, box, NULL, 0);
 
1780
        str = mon->mon_modelname ? mon->mon_modelname : "";
 
1781
        node->data->monitor.model =
 
1782
                XtVaCreateManagedWidget("modelname", asciiTextWidgetClass, box,
 
1783
                                        XtNeditType, XawtextEdit,
 
1784
                                        XtNstring, str,
 
1785
                                        NULL);
 
1786
 
 
1787
        XtCreateManagedWidget("widthL", labelWidgetClass, box, NULL, 0);
 
1788
        if (mon->mon_width)
 
1789
            XmuSnprintf(buf, sizeof(buf), "%d", mon->mon_width);
 
1790
        else
 
1791
            *buf = '\0';
 
1792
        node->data->monitor.width =
 
1793
                XtVaCreateManagedWidget("width", asciiTextWidgetClass, box,
 
1794
                                        XtNeditType, XawtextEdit,
 
1795
                                        XtNstring, buf,
 
1796
                                        NULL);
 
1797
 
 
1798
        XtCreateManagedWidget("heightL", labelWidgetClass, box, NULL, 0);
 
1799
        if (mon->mon_height)
 
1800
            XmuSnprintf(buf, sizeof(buf), "%d", mon->mon_height);
 
1801
        else
 
1802
            *buf = '\0';
 
1803
        node->data->monitor.height =
 
1804
                XtVaCreateManagedWidget("height", asciiTextWidgetClass, box,
 
1805
                                        XtNeditType, XawtextEdit,
 
1806
                                        XtNstring, buf,
 
1807
                                        NULL);
 
1808
 
 
1809
        XtCreateManagedWidget("hsyncL", labelWidgetClass, box, NULL, 0);
 
1810
        if (mon->mon_n_hsync > 0)
 
1811
            parser_range_to_string(buf, &(mon->mon_hsync[0]),
 
1812
                                   mon->mon_n_hsync);
 
1813
        else
 
1814
            *buf = '\0';
 
1815
        node->data->monitor.hsync =
 
1816
                XtVaCreateManagedWidget("hsync", asciiTextWidgetClass, box,
 
1817
                                        XtNeditType, XawtextEdit,
 
1818
                                        XtNstring, buf,
 
1819
                                        NULL);
 
1820
 
 
1821
        XtCreateManagedWidget("vrefreshL", labelWidgetClass, box, NULL, 0);
 
1822
        if (mon->mon_n_vrefresh > 0)
 
1823
            parser_range_to_string(buf, &(mon->mon_vrefresh[0]),
 
1824
                                   mon->mon_n_vrefresh);
 
1825
        else
 
1826
            *buf = '\0';
 
1827
        node->data->monitor.vrefresh =
 
1828
                XtVaCreateManagedWidget("vrefresh", asciiTextWidgetClass, box,
 
1829
                                        XtNeditType, XawtextEdit,
 
1830
                                        XtNstring, buf,
 
1831
                                        NULL);
 
1832
 
 
1833
        XtCreateManagedWidget("gammaRedL", labelWidgetClass, box, NULL, 0);
 
1834
        if (mon->mon_gamma_red) 
 
1835
            XmuSnprintf(buf, sizeof(buf), "%g", mon->mon_gamma_red);
 
1836
        else
 
1837
            *buf = '\0';
 
1838
        node->data->monitor.gammaRed =
 
1839
                XtVaCreateManagedWidget("gammaRed", asciiTextWidgetClass, box,
 
1840
                                        XtNeditType, XawtextEdit,
 
1841
                                        XtNstring, buf,
 
1842
                                        NULL);
 
1843
 
 
1844
        XtCreateManagedWidget("gammaGreenL", labelWidgetClass, box, NULL, 0);
 
1845
        if (mon->mon_gamma_green)
 
1846
            XmuSnprintf(buf, sizeof(buf), "%g", mon->mon_gamma_green);
 
1847
        else
 
1848
            *buf = '\0';
 
1849
        node->data->monitor.gammaGreen =
 
1850
                XtVaCreateManagedWidget("gammaGreen", asciiTextWidgetClass, box,
 
1851
                                        XtNeditType, XawtextEdit,
 
1852
                                        XtNstring, buf,
 
1853
                                        NULL);
 
1854
 
 
1855
        XtCreateManagedWidget("gammaBlueL", labelWidgetClass, box, NULL, 0);
 
1856
        if (mon->mon_gamma_blue)
 
1857
            XmuSnprintf(buf, sizeof(buf), "%g", mon->mon_gamma_blue);
 
1858
        else
 
1859
            *buf = '\0';
 
1860
        node->data->monitor.gammaBlue =
 
1861
                XtVaCreateManagedWidget("gammaBlue", asciiTextWidgetClass, box,
 
1862
                                        XtNeditType, XawtextEdit,
 
1863
                                        XtNstring, buf,
 
1864
                                        NULL);
 
1865
 
 
1866
        if ((prev = node->child) != NULL)
 
1867
            while (prev->next)
 
1868
                prev = prev->next;
 
1869
        command = XtVaCreateManagedWidget("ModeLine", toggleWidgetClass, tree,
 
1870
                                          XtNstate, True,
 
1871
                                          XtNtreeParent, box, NULL);
 
1872
        modeline = NewNode(node, command, command, node->node, NULL);
 
1873
        CreateMonitorModeLine(modeline,
 
1874
                              node->data->monitor.monitor->mon_modeline_lst);
 
1875
        if (prev == NULL)
 
1876
            prev = node->child = modeline;
 
1877
        else {
 
1878
            prev->next = modeline;
 
1879
            prev = prev->next;
 
1880
        }
 
1881
 
 
1882
        useModes = XtVaCreateManagedWidget("UseModes", toggleWidgetClass, tree,
 
1883
                                           XtNstate, True,
 
1884
                                           XtNtreeParent, box, NULL);
 
1885
        prev->next = modes = NewNode(node, useModes, useModes, node->node, NULL);
 
1886
        CreateMonitorModes(modes,
 
1887
                           node->data->monitor.monitor->mon_modes_sect_lst);
 
1888
    }
 
1889
    else {
 
1890
        command = XtCreateManagedWidget("new", commandWidgetClass, box,
 
1891
                                        NULL, 0);
 
1892
        XtAddCallback(command, XtNcallback, NewMonitorCallback, (XtPointer)node);
 
1893
        label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
1894
                                        XtNeditType, XawtextEdit,
 
1895
                                        NULL);
 
1896
        node->data->monitor.text = label;
 
1897
    }
 
1898
    if (XtIsRealized(node->treeParent))
 
1899
        XtRealizeWidget(box);
 
1900
    XtManageChild(box);
 
1901
}
 
1902
 
 
1903
static void
 
1904
MonitorDestroy(TreeNode *node)
 
1905
{
 
1906
    int i;
 
1907
    TreeNode *sc = screenTree;
 
1908
 
 
1909
    for (i = 0; i < computer.num_devices; i++)
 
1910
        if ((XF86ConfMonitorPtr)(computer.devices[i]->config) ==
 
1911
            node->data->monitor.monitor) {
 
1912
            config = computer.devices[i]->widget;
 
1913
            RemoveDeviceCallback(NULL, NULL, NULL);
 
1914
        }
 
1915
 
 
1916
    if (sc) {
 
1917
        TreeNode *prev;
 
1918
 
 
1919
        sc = prev = sc->child;
 
1920
        while (sc->next) {
 
1921
            TreeNode *next = sc->next;
 
1922
 
 
1923
            if (sc->data->screen.screen->scrn_monitor ==
 
1924
                node->data->monitor.monitor) {
 
1925
                XtDestroyWidget(sc->node);
 
1926
 
 
1927
                if (sc->child)
 
1928
                    DestroyTree(sc->child);
 
1929
                if (sc->data)
 
1930
                    XtFree((XtPointer)sc->data);
 
1931
                XtFree((XtPointer)sc);
 
1932
 
 
1933
                if (sc == screenTree->child)
 
1934
                    sc = prev = next = screenTree->child = next;
 
1935
                else
 
1936
                    prev->next = sc = next;
 
1937
                continue;
 
1938
            }
 
1939
            prev = sc;
 
1940
            sc = next;
 
1941
        }
 
1942
    }
 
1943
}
 
1944
 
 
1945
static void
 
1946
NewMonitorCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
1947
{
 
1948
    TreeNode *parent, *node = (TreeNode*)user_data;
 
1949
    XF86ConfMonitorPtr mon;
 
1950
    Arg args[1];
 
1951
    char *label;
 
1952
 
 
1953
    XtSetArg(args[0], XtNstring, &label);
 
1954
    XtGetValues(node->data->monitor.text, args, 1);
 
1955
    if (*label == '\0')
 
1956
        return;
 
1957
 
 
1958
    parent = node->parent;
 
1959
    DeleteNode(node);
 
1960
    mon = (XF86ConfMonitorPtr)XtCalloc(1, sizeof(XF86ConfMonitorRec));
 
1961
    mon->mon_identifier = XtNewString(label);
 
1962
    XF86Config->conf_monitor_lst =
 
1963
        xf86addMonitor(XF86Config->conf_monitor_lst, mon);
 
1964
 
 
1965
    CreateMonitor(parent, mon);
 
1966
 
 
1967
    RelayoutTree();
 
1968
}
 
1969
 
 
1970
static void
 
1971
MonitorUpdate(TreeNode *node)
 
1972
{
 
1973
    char *str;
 
1974
 
 
1975
    /* vendor */
 
1976
    XtVaGetValues(node->data->monitor.vendor, XtNstring, &str, NULL);
 
1977
    XtFree(node->data->monitor.monitor->mon_vendor);
 
1978
    if (*str)
 
1979
        node->data->monitor.monitor->mon_vendor = XtNewString(str);
 
1980
    else
 
1981
        node->data->monitor.monitor->mon_vendor = NULL;
 
1982
 
 
1983
    /* model */
 
1984
    XtVaGetValues(node->data->monitor.model, XtNstring, &str, NULL);
 
1985
    XtFree(node->data->monitor.monitor->mon_modelname);
 
1986
    if (*str)
 
1987
        node->data->monitor.monitor->mon_modelname = XtNewString(str);
 
1988
    else
 
1989
        node->data->monitor.monitor->mon_modelname = NULL;
 
1990
 
 
1991
    /* width */
 
1992
    XtVaGetValues(node->data->monitor.width, XtNstring, &str, NULL);
 
1993
    node->data->monitor.monitor->mon_width = strtoul(str, NULL, 0);
 
1994
 
 
1995
    /* height */
 
1996
    XtVaGetValues(node->data->monitor.height, XtNstring, &str, NULL);
 
1997
    node->data->monitor.monitor->mon_height = strtoul(str, NULL, 0);
 
1998
 
 
1999
    /* hsync */
 
2000
    XtVaGetValues(node->data->monitor.hsync, XtNstring, &str, NULL);
 
2001
    node->data->monitor.monitor->mon_n_hsync =
 
2002
        string_to_parser_range(str,
 
2003
                               &(node->data->monitor.monitor->mon_hsync[0]),
 
2004
                               CONF_MAX_HSYNC);
 
2005
 
 
2006
    /* vrefresh */
 
2007
    XtVaGetValues(node->data->monitor.vrefresh, XtNstring, &str, NULL);
 
2008
    node->data->monitor.monitor->mon_n_vrefresh =
 
2009
        string_to_parser_range(str,
 
2010
                               &(node->data->monitor.monitor->mon_vrefresh[0]),
 
2011
                               CONF_MAX_VREFRESH);
 
2012
 
 
2013
    /* gammaRed */
 
2014
    XtVaGetValues(node->data->monitor.gammaRed, XtNstring, &str, NULL);
 
2015
    node->data->monitor.monitor->mon_gamma_red = strtod(str, NULL);
 
2016
 
 
2017
    /* gammaGreen */
 
2018
    XtVaGetValues(node->data->monitor.gammaGreen, XtNstring, &str, NULL);
 
2019
    node->data->monitor.monitor->mon_gamma_green = strtod(str, NULL);
 
2020
 
 
2021
    /* gammaBlue */
 
2022
    XtVaGetValues(node->data->monitor.gammaBlue, XtNstring, &str, NULL);
 
2023
    node->data->monitor.monitor->mon_gamma_blue = strtod(str, NULL);
 
2024
}
 
2025
 
 
2026
static void
 
2027
CreateMonitorModeLine(TreeNode *parent, XF86ConfModeLinePtr modeline)
 
2028
{
 
2029
    TreeNode *node, *prev;
 
2030
    TreeData *data;
 
2031
 
 
2032
    if ((prev = parent->child) != NULL)
 
2033
        while (prev->next)
 
2034
            prev = prev->next;
 
2035
 
 
2036
    while (modeline) {
 
2037
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
2038
        data->modeline.modeline = modeline;
 
2039
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
2040
        node->destroy = MonitorModeLineDestroy;
 
2041
        CreateModeLineField(node, False, True);
 
2042
        if (parent->child == NULL)
 
2043
            parent->child = node;
 
2044
        else
 
2045
            prev->next = node;
 
2046
        prev = node;
 
2047
        modeline = (XF86ConfModeLinePtr)(modeline->list.next);
 
2048
    }
 
2049
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
2050
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
2051
    if (parent->child == NULL)
 
2052
        parent->child = node;
 
2053
    else
 
2054
        prev->next = node;
 
2055
    prev = node;
 
2056
    CreateModeLineField(node, True, True);
 
2057
}
 
2058
 
 
2059
/*ARGUSED*/
 
2060
static void
 
2061
MonitorModeLineDestroy(TreeNode *node)
 
2062
{
 
2063
    if (node->data->modeline.modeline)
 
2064
        xf86removeMonitorModeLine(node->parent->parent->data->monitor.monitor,
 
2065
                                  node->data->modeline.modeline);
 
2066
}
 
2067
 
 
2068
/*ARGSUSED*/
 
2069
static void
 
2070
NewMonitorModeLineCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
2071
{
 
2072
    TreeNode *parent, *node = (TreeNode*)user_data;
 
2073
    XF86ConfModeLinePtr modeline;
 
2074
    Arg args[1];
 
2075
    char *ident, *value;
 
2076
 
 
2077
    XtSetArg(args[0], XtNstring, &ident);
 
2078
    XtGetValues(node->data->modeline.text, args, 1);
 
2079
    XtSetArg(args[0], XtNstring, &value);
 
2080
    XtGetValues(node->data->modeline.value, args, 1);
 
2081
    if (*ident == '\0' || *value == '\0')
 
2082
        return;
 
2083
 
 
2084
    parent = node->parent;
 
2085
    DeleteNode(node);
 
2086
    modeline = ParseModeLine(ident, value);
 
2087
    parent->parent->data->monitor.monitor->mon_modeline_lst =
 
2088
        xf86addModeLine(parent->parent->data->monitor.monitor->mon_modeline_lst,
 
2089
                        modeline);
 
2090
 
 
2091
    CreateMonitorModeLine(parent, modeline);
 
2092
    RelayoutTree();
 
2093
}
 
2094
 
 
2095
static void
 
2096
CreateMonitorModes(TreeNode *parent, XF86ConfModesLinkPtr lnk)
 
2097
{
 
2098
    TreeNode *node, *prev;
 
2099
    TreeData *data;
 
2100
 
 
2101
    if ((prev = parent->child) != NULL)
 
2102
        while (prev->next)
 
2103
            prev = prev->next;
 
2104
 
 
2105
    while (lnk) {
 
2106
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
2107
        data->modeslink.modeslink = lnk;
 
2108
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
2109
        node->destroy = MonitorModesLinkDestroy;
 
2110
        CreateMonitorModesField(node, False);
 
2111
        if (parent->child == NULL)
 
2112
            parent->child = node;
 
2113
        else
 
2114
            prev->next = node;
 
2115
        prev = node;
 
2116
        lnk = (XF86ConfModesLinkPtr)(lnk->list.next);
 
2117
    }
 
2118
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
2119
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
2120
    if (parent->child == NULL)
 
2121
        parent->child = node;
 
2122
    else
 
2123
        prev->next = node;
 
2124
    prev = node;
 
2125
    CreateMonitorModesField(node, True);
 
2126
}
 
2127
 
 
2128
static void
 
2129
CreateMonitorModesField(TreeNode *node, Bool addnew)
 
2130
{
 
2131
    Widget box, command;
 
2132
 
 
2133
    box = XtVaCreateWidget("modes", formWidgetClass, tree,
 
2134
                           XtNtreeParent, node->treeParent, NULL);
 
2135
    node->node = box;
 
2136
 
 
2137
    if (!addnew) {
 
2138
        XF86ConfModesLinkPtr lnk = node->data->modeslink.modeslink;
 
2139
 
 
2140
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
2141
                                        NULL, 0);
 
2142
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
2143
        (void) XtVaCreateManagedWidget("mode", labelWidgetClass, box,
 
2144
                                        XtNlabel, lnk->ml_modes_str, NULL);
 
2145
    }
 
2146
    else {
 
2147
        Widget sme;
 
2148
        XF86ConfModesPtr ptr = XF86Config->conf_modes_lst;
 
2149
 
 
2150
        command = XtVaCreateManagedWidget("new", menuButtonWidgetClass, box,
 
2151
                                          XtNmenuName, "modesMenu", NULL);
 
2152
        node->data->modeslink.menu =
 
2153
            XtVaCreatePopupShell("modesMenu", simpleMenuWidgetClass, box,
 
2154
                                 XtNleftMargin, 1, XtNrightMargin, 1,
 
2155
                                 XtNtopMargin, 1, XtNbottomMargin, 1,
 
2156
                                 NULL);
 
2157
        while (ptr) {
 
2158
            sme = XtCreateManagedWidget(ptr->modes_identifier, smeBSBObjectClass,
 
2159
                                        node->data->modeslink.menu, NULL, 0);
 
2160
            XtAddCallback(sme, XtNcallback, NewMonitorModesCallback,
 
2161
                          (XtPointer)node);
 
2162
            ptr = (XF86ConfModesPtr)(ptr->list.next);
 
2163
        }
 
2164
    }
 
2165
    if (XtIsRealized(node->treeParent))
 
2166
        XtRealizeWidget(box);
 
2167
    XtManageChild(box);
 
2168
}
 
2169
 
 
2170
/*ARGUSED*/
 
2171
static void
 
2172
MonitorModesLinkDestroy(TreeNode *node)
 
2173
{
 
2174
    if (node->data->modeslink.modeslink)
 
2175
        xf86removeMonitorModesLink(node->parent->parent->data->monitor.monitor,
 
2176
                                   node->data->modeslink.modeslink);
 
2177
}
 
2178
 
 
2179
/*ARGSUSED*/
 
2180
static void
 
2181
NewMonitorModesCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
2182
{
 
2183
    TreeNode *parent, *node = (TreeNode*)user_data;
 
2184
    XF86ConfModesLinkPtr link;
 
2185
    char *ident = XtName(w);
 
2186
 
 
2187
    parent = node->parent;
 
2188
    DeleteNode(node);
 
2189
    link = (XF86ConfModesLinkPtr)XtCalloc(1, sizeof(XF86ConfModesLinkRec));
 
2190
    link->ml_modes_str = XtNewString(ident);
 
2191
    parent->parent->data->monitor.monitor->mon_modes_sect_lst =
 
2192
        xf86addModesLink(parent->parent->data->monitor.monitor->mon_modes_sect_lst,
 
2193
                        link);
 
2194
 
 
2195
    CreateMonitorModes(parent, link);
 
2196
    RelayoutTree();
 
2197
}
 
2198
 
 
2199
/* Device */
 
2200
static void
 
2201
CreateDevice(TreeNode *parent, XF86ConfDevicePtr dev)
 
2202
{
 
2203
    TreeNode *prev, *node;
 
2204
    TreeData *data;
 
2205
 
 
2206
    if ((prev = parent->child) != NULL)
 
2207
        while (prev->next)
 
2208
            prev = prev->next;
 
2209
 
 
2210
    while (dev) {
 
2211
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
2212
        data->device.device = dev;
 
2213
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
2214
        node->destroy = DeviceDestroy;
 
2215
        node->update = DeviceUpdate;
 
2216
        CreateDeviceField(node, False);
 
2217
        if (parent->child == NULL)
 
2218
            parent->child = node;
 
2219
        else
 
2220
            prev->next = node;
 
2221
        prev = node;
 
2222
        dev = (XF86ConfDevicePtr)(dev->list.next);
 
2223
    }
 
2224
 
 
2225
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
2226
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
2227
    CreateDeviceField(node, True);
 
2228
    if (parent->child == NULL)
 
2229
        parent->child = node;
 
2230
    else
 
2231
        prev->next = node;
 
2232
}
 
2233
 
 
2234
static void
 
2235
CreateDeviceField(TreeNode *node, Bool addnew)
 
2236
{
 
2237
    Widget box, command, label;
 
2238
 
 
2239
    box = XtVaCreateWidget("device", formWidgetClass, tree,
 
2240
                           XtNtreeParent, node->treeParent, NULL);
 
2241
    node->node = box;
 
2242
 
 
2243
    if (!addnew) {
 
2244
        int i, tmp, len;
 
2245
        char buf[1024], *str;
 
2246
        XF86OptionPtr *options;
 
2247
        XF86ConfDevicePtr dev = node->data->device.device;
 
2248
 
 
2249
        options = &(dev->dev_option_lst);
 
2250
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
2251
                                        NULL, 0);
 
2252
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
2253
        command = XtCreateManagedWidget("options", commandWidgetClass, box,
 
2254
                                        NULL, 0);
 
2255
        XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
 
2256
        label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
2257
                                        XtNlabel, dev->dev_identifier, NULL);
 
2258
 
 
2259
        XtCreateManagedWidget("vendorL", labelWidgetClass, box, NULL, 0);
 
2260
        str = dev->dev_vendor ? dev->dev_vendor : "";
 
2261
        node->data->device.vendor =
 
2262
                XtVaCreateManagedWidget("vendor", asciiTextWidgetClass, box,
 
2263
                                        XtNeditType, XawtextEdit,
 
2264
                                        XtNstring, str,
 
2265
                                        NULL);
 
2266
 
 
2267
        XtCreateManagedWidget("boardL", labelWidgetClass, box, NULL, 0);
 
2268
        str = dev->dev_board ? dev->dev_board : "";
 
2269
        node->data->device.board =
 
2270
                XtVaCreateManagedWidget("board", asciiTextWidgetClass, box,
 
2271
                                        XtNeditType, XawtextEdit,
 
2272
                                        XtNstring, str,
 
2273
                                        NULL);
 
2274
 
 
2275
        XtCreateManagedWidget("chipsetL", labelWidgetClass, box, NULL, 0);
 
2276
        str = dev->dev_chipset ? dev->dev_chipset : "";
 
2277
        node->data->device.chipset =
 
2278
                XtVaCreateManagedWidget("chipset", asciiTextWidgetClass, box,
 
2279
                                        XtNeditType, XawtextEdit,
 
2280
                                        XtNstring, str,
 
2281
                                        NULL);
 
2282
 
 
2283
        XtCreateManagedWidget("busidL", labelWidgetClass, box, NULL, 0);
 
2284
        str = dev->dev_busid ? dev->dev_busid : "";
 
2285
        node->data->device.busid =
 
2286
                XtVaCreateManagedWidget("busid", asciiTextWidgetClass, box,
 
2287
                                        XtNeditType, XawtextEdit,
 
2288
                                        XtNstring, str,
 
2289
                                        NULL);
 
2290
 
 
2291
        XtCreateManagedWidget("cardL", labelWidgetClass, box, NULL, 0);
 
2292
        str = dev->dev_card ? dev->dev_card : "";
 
2293
        node->data->device.card =
 
2294
                XtVaCreateManagedWidget("card", asciiTextWidgetClass, box,
 
2295
                                        XtNeditType, XawtextEdit,
 
2296
                                        XtNstring, str,
 
2297
                                        NULL);
 
2298
 
 
2299
        XtCreateManagedWidget("driverL", labelWidgetClass, box, NULL, 0);
 
2300
        str = dev->dev_driver ? dev->dev_driver : "";
 
2301
        node->data->device.driver =
 
2302
                XtVaCreateManagedWidget("driver", asciiTextWidgetClass, box,
 
2303
                                        XtNeditType, XawtextEdit,
 
2304
                                        XtNstring, str,
 
2305
                                        NULL);
 
2306
 
 
2307
        XtCreateManagedWidget("ramdacL", labelWidgetClass, box, NULL, 0);
 
2308
        str = dev->dev_ramdac ? dev->dev_ramdac : "";
 
2309
        node->data->device.ramdac =
 
2310
                XtVaCreateManagedWidget("ramdac", asciiTextWidgetClass, box,
 
2311
                                        XtNeditType, XawtextEdit,
 
2312
                                        XtNstring, str,
 
2313
                                        NULL);
 
2314
 
 
2315
        XtCreateManagedWidget("dacSpeedL", labelWidgetClass, box, NULL, 0);
 
2316
        if (dev->dev_dacSpeeds[0] > 0) {
 
2317
            for (i = len = 0; i < CONF_MAXDACSPEEDS &&
 
2318
                              dev->dev_dacSpeeds[i] > 0; i++) {
 
2319
                tmp = XmuSnprintf(buf + len, sizeof(buf) - len, "%g ",
 
2320
                                  dev->dev_dacSpeeds[i] / 1000.);
 
2321
                len += tmp;
 
2322
            }
 
2323
        }
 
2324
        else
 
2325
            *buf = '\0';
 
2326
        node->data->device.dacSpeed =
 
2327
                XtVaCreateManagedWidget("dacSpeed", asciiTextWidgetClass, box,
 
2328
                                        XtNeditType, XawtextEdit,
 
2329
                                        XtNstring, buf,
 
2330
                                        NULL);
 
2331
 
 
2332
        XtCreateManagedWidget("videoRamL", labelWidgetClass, box, NULL, 0);
 
2333
        if (dev->dev_videoram)
 
2334
            XmuSnprintf(buf, sizeof(buf), "%d", dev->dev_videoram);
 
2335
        else
 
2336
            *buf = '\0';
 
2337
        node->data->device.videoRam =
 
2338
                XtVaCreateManagedWidget("videoRam", asciiTextWidgetClass, box,
 
2339
                                        XtNeditType, XawtextEdit,
 
2340
                                        XtNstring, buf,
 
2341
                                        NULL);
 
2342
 
 
2343
        XtCreateManagedWidget("textClockFreqL", labelWidgetClass, box, NULL, 0);
 
2344
        if (dev->dev_textclockfreq)
 
2345
            XmuSnprintf(buf, sizeof(buf), "%.1f",
 
2346
                        (double)dev->dev_textclockfreq / 1000.0);
 
2347
        else
 
2348
            *buf = '\0';
 
2349
        node->data->device.textClockFreq =
 
2350
                XtVaCreateManagedWidget("textClockFreq", asciiTextWidgetClass, box,
 
2351
                                        XtNeditType, XawtextEdit,
 
2352
                                        XtNstring, buf,
 
2353
                                        NULL);
 
2354
 
 
2355
        XtCreateManagedWidget("biosBaseL", labelWidgetClass, box, NULL, 0);
 
2356
        if (dev->dev_bios_base)
 
2357
            XmuSnprintf(buf, sizeof(buf), "0x%lx", dev->dev_bios_base);
 
2358
        else
 
2359
            *buf = '\0';
 
2360
        node->data->device.biosBase =
 
2361
                XtVaCreateManagedWidget("biosBase", asciiTextWidgetClass, box,
 
2362
                                        XtNeditType, XawtextEdit,
 
2363
                                        XtNstring, buf,
 
2364
                                        NULL);
 
2365
 
 
2366
        XtCreateManagedWidget("memBaseL", labelWidgetClass, box, NULL, 0);
 
2367
        if (dev->dev_mem_base)
 
2368
            XmuSnprintf(buf, sizeof(buf), "0x%lx", dev->dev_mem_base);
 
2369
        else
 
2370
            *buf = '\0';
 
2371
        node->data->device.memBase =
 
2372
                XtVaCreateManagedWidget("memBase", asciiTextWidgetClass, box,
 
2373
                                        XtNeditType, XawtextEdit,
 
2374
                                        XtNstring, buf,
 
2375
                                        NULL);
 
2376
 
 
2377
        XtCreateManagedWidget("ioBaseL", labelWidgetClass, box, NULL, 0);
 
2378
        if (dev->dev_io_base)
 
2379
            XmuSnprintf(buf, sizeof(buf), "0x%lx", dev->dev_io_base);
 
2380
        else
 
2381
            *buf = '\0';
 
2382
        node->data->device.ioBase =
 
2383
                XtVaCreateManagedWidget("ioBase", asciiTextWidgetClass, box,
 
2384
                                        XtNeditType, XawtextEdit,
 
2385
                                        XtNstring, buf,
 
2386
                                        NULL);
 
2387
 
 
2388
        XtCreateManagedWidget("clockChipL", labelWidgetClass, box, NULL, 0);
 
2389
        str = dev->dev_clockchip ? dev->dev_clockchip : "";
 
2390
        node->data->device.clockChip =
 
2391
                XtVaCreateManagedWidget("clockChip", asciiTextWidgetClass, box,
 
2392
                                        XtNeditType, XawtextEdit,
 
2393
                                        XtNstring, str,
 
2394
                                        NULL);
 
2395
 
 
2396
        *buf = '\0';
 
2397
        for (i = len = 0; i < dev->dev_clocks; i++) {
 
2398
            tmp = XmuSnprintf(buf + len, sizeof(buf) - len, "%.1f ",
 
2399
                              (double)dev->dev_clock[i] / 1000.0);
 
2400
            len += tmp;
 
2401
        }
 
2402
        XtCreateManagedWidget("devClockL", labelWidgetClass, box, NULL, 0);
 
2403
        node->data->device.devClock =
 
2404
                XtVaCreateManagedWidget("devClock", asciiTextWidgetClass, box,
 
2405
                                        XtNeditType, XawtextEdit,
 
2406
                                        XtNstring, buf,
 
2407
                                        NULL);
 
2408
 
 
2409
        XtCreateManagedWidget("chipIdL", labelWidgetClass, box, NULL, 0);
 
2410
        if (dev->dev_chipid != -1)
 
2411
            XmuSnprintf(buf, sizeof(buf), "0x%x", dev->dev_chipid);
 
2412
        else
 
2413
            *buf = '\0';
 
2414
        node->data->device.chipId =
 
2415
                XtVaCreateManagedWidget("chipId", asciiTextWidgetClass, box,
 
2416
                                        XtNeditType, XawtextEdit,
 
2417
                                        XtNstring, buf,
 
2418
                                        NULL);
 
2419
 
 
2420
        XtCreateManagedWidget("chipRevL", labelWidgetClass, box, NULL, 0);
 
2421
        if (dev->dev_chiprev != -1)
 
2422
            XmuSnprintf(buf, sizeof(buf), "0x%x", dev->dev_chiprev);
 
2423
        else
 
2424
            *buf = '\0';
 
2425
        node->data->device.chipRev =
 
2426
                XtVaCreateManagedWidget("chipRev", asciiTextWidgetClass, box,
 
2427
                                        XtNeditType, XawtextEdit,
 
2428
                                        XtNstring, buf,
 
2429
                                        NULL);
 
2430
 
 
2431
        XtCreateManagedWidget("irqL", labelWidgetClass, box, NULL, 0);
 
2432
        if (dev->dev_irq != -1)
 
2433
            XmuSnprintf(buf, sizeof(buf), "%d", dev->dev_irq);
 
2434
        else
 
2435
            *buf = '\0';
 
2436
        node->data->device.irq =
 
2437
                XtVaCreateManagedWidget("irq", asciiTextWidgetClass, box,
 
2438
                                        XtNeditType, XawtextEdit,
 
2439
                                        XtNstring, buf,
 
2440
                                        NULL);
 
2441
 
 
2442
        XtCreateManagedWidget("screenL", labelWidgetClass, box, NULL, 0);
 
2443
        if (dev->dev_screen > 0)
 
2444
            XmuSnprintf(buf, sizeof(buf), "%d", dev->dev_screen);
 
2445
        else
 
2446
            *buf = '\0';
 
2447
        node->data->device.screen =
 
2448
                XtVaCreateManagedWidget("screen", asciiTextWidgetClass, box,
 
2449
                                        XtNeditType, XawtextEdit,
 
2450
                                        XtNstring, buf,
 
2451
                                        NULL);
 
2452
    }
 
2453
    else {
 
2454
        command = XtCreateManagedWidget("new", commandWidgetClass, box,
 
2455
                                        NULL, 0);
 
2456
        XtAddCallback(command, XtNcallback, NewDeviceCallback, (XtPointer)node);
 
2457
        label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
2458
                                        XtNeditType, XawtextEdit,
 
2459
                                        NULL);
 
2460
        node->data->device.text = label;
 
2461
    }
 
2462
    if (XtIsRealized(node->treeParent))
 
2463
        XtRealizeWidget(box);
 
2464
    XtManageChild(box);
 
2465
}
 
2466
 
 
2467
static void
 
2468
NewDeviceCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
2469
{
 
2470
    TreeNode *parent, *node = (TreeNode*)user_data;
 
2471
    XF86ConfDevicePtr dev;
 
2472
    Arg args[1];
 
2473
    char *label;
 
2474
 
 
2475
    XtSetArg(args[0], XtNstring, &label);
 
2476
    XtGetValues(node->data->device.text, args, 1);
 
2477
    if (*label == '\0')
 
2478
        return;
 
2479
 
 
2480
    parent = node->parent;
 
2481
    DeleteNode(node);
 
2482
    dev = (XF86ConfDevicePtr)XtCalloc(1, sizeof(XF86ConfDeviceRec));
 
2483
    dev->dev_identifier = XtNewString(label);
 
2484
    dev->dev_chipid = -1;
 
2485
    dev->dev_chiprev = -1;
 
2486
    dev->dev_irq = -1;
 
2487
 
 
2488
    XF86Config->conf_device_lst =
 
2489
        xf86addDevice(XF86Config->conf_device_lst, dev);
 
2490
 
 
2491
    CreateDevice(parent, dev);
 
2492
 
 
2493
    RelayoutTree();
 
2494
}
 
2495
 
 
2496
static void
 
2497
DeviceDestroy(TreeNode *node)
 
2498
{
 
2499
    int i;
 
2500
    TreeNode *sc = screenTree;
 
2501
 
 
2502
    for (i = 0; i < computer.num_devices; i++)
 
2503
        if ((XF86ConfDevicePtr)(computer.devices[i]->config) ==
 
2504
            node->data->device.device) {
 
2505
            config = computer.devices[i]->widget;
 
2506
            RemoveDeviceCallback(NULL, NULL, NULL);
 
2507
        }
 
2508
 
 
2509
    if (sc) {
 
2510
        TreeNode *prev;
 
2511
 
 
2512
        sc = prev = sc->child;
 
2513
        while (sc->next) {
 
2514
            TreeNode *next = sc->next;
 
2515
 
 
2516
            if (sc->data->screen.screen->scrn_monitor ==
 
2517
                node->data->monitor.monitor) {
 
2518
                XtDestroyWidget(sc->node);
 
2519
 
 
2520
                if (sc->child)
 
2521
                    DestroyTree(sc->child);
 
2522
                if (sc->data)
 
2523
                    XtFree((XtPointer)sc->data);
 
2524
                XtFree((XtPointer)sc);
 
2525
 
 
2526
                if (sc == screenTree->child)
 
2527
                    sc = prev = next = screenTree->child = next;
 
2528
                else
 
2529
                    prev->next = sc = next;
 
2530
                continue;
 
2531
            }
 
2532
            prev = sc;
 
2533
            sc = next;
 
2534
        }
 
2535
    }
 
2536
}
 
2537
 
 
2538
static void
 
2539
DeviceUpdate(TreeNode *node)
 
2540
{
 
2541
    int i;
 
2542
    char *str, *tmp;
 
2543
 
 
2544
    /* vendor */
 
2545
    XtVaGetValues(node->data->device.vendor, XtNstring, &str, NULL);
 
2546
    XtFree(node->data->device.device->dev_vendor);
 
2547
    if (*str)
 
2548
        node->data->device.device->dev_vendor = XtNewString(str);
 
2549
    else
 
2550
        node->data->device.device->dev_vendor = NULL;
 
2551
 
 
2552
    /* board */
 
2553
    XtVaGetValues(node->data->device.board, XtNstring, &str, NULL);
 
2554
    XtFree(node->data->device.device->dev_board);
 
2555
    if (*str)
 
2556
        node->data->device.device->dev_board = XtNewString(str);
 
2557
    else
 
2558
        node->data->device.device->dev_board = NULL;
 
2559
 
 
2560
    /* chipset */
 
2561
    XtVaGetValues(node->data->device.chipset, XtNstring, &str, NULL);
 
2562
    XtFree(node->data->device.device->dev_chipset);
 
2563
    if (*str)
 
2564
        node->data->device.device->dev_chipset = XtNewString(str);
 
2565
    else
 
2566
        node->data->device.device->dev_chipset = NULL;
 
2567
 
 
2568
    /* busid */
 
2569
    XtVaGetValues(node->data->device.busid, XtNstring, &str, NULL);
 
2570
    XtFree(node->data->device.device->dev_busid);
 
2571
    if (*str)
 
2572
        node->data->device.device->dev_busid = XtNewString(str);
 
2573
    else
 
2574
        node->data->device.device->dev_busid = NULL;
 
2575
 
 
2576
    /* card */
 
2577
    XtVaGetValues(node->data->device.card, XtNstring, &str, NULL);
 
2578
    XtFree(node->data->device.device->dev_card);
 
2579
    if (*str)
 
2580
        node->data->device.device->dev_card = XtNewString(str);
 
2581
    else
 
2582
        node->data->device.device->dev_card = NULL;
 
2583
 
 
2584
    /* driver */
 
2585
    XtVaGetValues(node->data->device.driver, XtNstring, &str, NULL);
 
2586
    XtFree(node->data->device.device->dev_driver);
 
2587
    if (*str)
 
2588
        node->data->device.device->dev_driver = XtNewString(str);
 
2589
    else
 
2590
        node->data->device.device->dev_driver = NULL;
 
2591
 
 
2592
    /* ramdac */
 
2593
    XtVaGetValues(node->data->device.ramdac, XtNstring, &str, NULL);
 
2594
    XtFree(node->data->device.device->dev_ramdac);
 
2595
    if (*str)
 
2596
        node->data->device.device->dev_ramdac = XtNewString(str);
 
2597
    else
 
2598
        node->data->device.device->dev_ramdac = NULL;
 
2599
 
 
2600
    /* dacSpeed */
 
2601
    tmp = NULL;
 
2602
    XtVaGetValues(node->data->device.dacSpeed, XtNstring, &str, NULL);
 
2603
    for (i = 0; i < CONF_MAXDACSPEEDS && str != tmp; i++) {
 
2604
        if ((node->data->device.device->dev_dacSpeeds[i] =
 
2605
            (strtod(str, &tmp) * 1000. + .5)) == 0)
 
2606
            break;
 
2607
        str = tmp;
 
2608
        while (isspace(*str))
 
2609
            ++str;
 
2610
    }
 
2611
 
 
2612
    /* videoRam */
 
2613
    XtVaGetValues(node->data->device.videoRam, XtNstring, &str, NULL);
 
2614
    node->data->device.device->dev_videoram = strtoul(str, NULL, 0);
 
2615
 
 
2616
    /* textClockFreq */
 
2617
    XtVaGetValues(node->data->device.textClockFreq, XtNstring, &str, NULL);
 
2618
    node->data->device.device->dev_textclockfreq =
 
2619
        strtod(str, NULL) * 1000. + .5;
 
2620
 
 
2621
    /* biosBase */
 
2622
    XtVaGetValues(node->data->device.biosBase, XtNstring, &str, NULL);
 
2623
    node->data->device.device->dev_bios_base = strtoul(str, NULL, 0);
 
2624
 
 
2625
    /* memBase */
 
2626
    XtVaGetValues(node->data->device.memBase, XtNstring, &str, NULL);
 
2627
    node->data->device.device->dev_mem_base = strtoul(str, NULL, 0);
 
2628
 
 
2629
    /* ioBase */
 
2630
    XtVaGetValues(node->data->device.ioBase, XtNstring, &str, NULL);
 
2631
    node->data->device.device->dev_io_base = strtoul(str, NULL, 0);
 
2632
 
 
2633
    /* clockChip */
 
2634
    XtVaGetValues(node->data->device.clockChip, XtNstring, &str, NULL);
 
2635
    XtFree(node->data->device.device->dev_clockchip);
 
2636
    if (*str)
 
2637
        node->data->device.device->dev_clockchip = XtNewString(str);
 
2638
    else
 
2639
        node->data->device.device->dev_clockchip = NULL;
 
2640
 
 
2641
    /* devSpeed */
 
2642
    tmp = NULL;
 
2643
    XtVaGetValues(node->data->device.devClock, XtNstring, &str, NULL);
 
2644
    for (i = 0; i < CONF_MAXCLOCKS && str != tmp; i++) {
 
2645
        if ((node->data->device.device->dev_clock[i] =
 
2646
             (strtod(str, &tmp) * 1000. + .5)) == 0)
 
2647
            break;
 
2648
        str = tmp;
 
2649
        while (isspace(*str))
 
2650
            ++str;
 
2651
    }
 
2652
    node->data->device.device->dev_clocks = i;
 
2653
 
 
2654
    /* chipId */
 
2655
    XtVaGetValues(node->data->device.chipId, XtNstring, &str, NULL);
 
2656
    if (*str)
 
2657
        node->data->device.device->dev_chipid = strtoul(str, NULL, 0);
 
2658
    else
 
2659
        node->data->device.device->dev_chipid = -1;
 
2660
 
 
2661
    /* chipRev */
 
2662
    XtVaGetValues(node->data->device.chipRev, XtNstring, &str, NULL);
 
2663
    if (*str)
 
2664
        node->data->device.device->dev_chiprev = strtoul(str, NULL, 0);
 
2665
    else
 
2666
        node->data->device.device->dev_chiprev = -1;
 
2667
 
 
2668
    /* irq */
 
2669
    XtVaGetValues(node->data->device.irq, XtNstring, &str, NULL);
 
2670
    if (*str)
 
2671
        node->data->device.device->dev_irq = strtoul(str, NULL, 0);
 
2672
    else
 
2673
        node->data->device.device->dev_irq = -1;
 
2674
 
 
2675
    /* screen */
 
2676
    XtVaGetValues(node->data->device.screen, XtNstring, &str, NULL);
 
2677
    if (*str)
 
2678
        node->data->device.device->dev_screen = strtoul(str, NULL, 0);
 
2679
    else
 
2680
        node->data->device.device->dev_screen = -1;
 
2681
}
 
2682
 
 
2683
/* Screen */
 
2684
static void
 
2685
CreateScreen(TreeNode *parent, XF86ConfScreenPtr scrn)
 
2686
{
 
2687
    TreeNode *prev, *node;
 
2688
    TreeData *data;
 
2689
 
 
2690
    if ((prev = parent->child) != NULL)
 
2691
        while (prev->next)
 
2692
            prev = prev->next;
 
2693
 
 
2694
    while (scrn) {
 
2695
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
2696
        data->screen.screen = scrn;
 
2697
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
2698
        node->destroy = ScreenDestroy;
 
2699
        node->update = ScreenUpdate;
 
2700
        CreateScreenField(node, False);
 
2701
        if (parent->child == NULL)
 
2702
            parent->child = node;
 
2703
        else
 
2704
            prev->next = node;
 
2705
        prev = node;
 
2706
        scrn = (XF86ConfScreenPtr)(scrn->list.next);
 
2707
    }
 
2708
 
 
2709
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
2710
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
2711
    CreateScreenField(node, True);
 
2712
    if (parent->child == NULL)
 
2713
        parent->child = node;
 
2714
    else
 
2715
        prev->next = node;
 
2716
}
 
2717
 
 
2718
static void
 
2719
CreateScreenField(TreeNode *node, Bool addnew)
 
2720
{
 
2721
    Widget box, command, label;
 
2722
 
 
2723
    box = XtVaCreateWidget("screen", formWidgetClass, tree,
 
2724
                           XtNtreeParent, node->treeParent, NULL);
 
2725
    node->node = box;
 
2726
 
 
2727
    if (!addnew) {
 
2728
        char buf[256], *str;
 
2729
        XF86OptionPtr *options;
 
2730
        TreeNode *adaptor, *display;
 
2731
        XF86ConfScreenPtr scrn = node->data->screen.screen;
 
2732
 
 
2733
        options = &(scrn->scrn_option_lst);
 
2734
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
2735
                                        NULL, 0);
 
2736
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
2737
        command = XtCreateManagedWidget("options", commandWidgetClass, box,
 
2738
                                        NULL, 0);
 
2739
        XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
 
2740
        label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
2741
                                        XtNlabel, scrn->scrn_identifier, NULL);
 
2742
 
 
2743
        XtCreateManagedWidget("defaultDepthL", labelWidgetClass, box, NULL, 0);
 
2744
        if (scrn->scrn_defaultdepth)
 
2745
            XmuSnprintf(buf, sizeof(buf), "%d", scrn->scrn_defaultdepth);
 
2746
        else
 
2747
            *buf = '\0';
 
2748
        node->data->screen.defaultDepth =
 
2749
                XtVaCreateManagedWidget("defaultDepth", asciiTextWidgetClass, box,
 
2750
                                        XtNeditType, XawtextEdit,
 
2751
                                        XtNstring, buf,
 
2752
                                        NULL);
 
2753
 
 
2754
        XtCreateManagedWidget("defaultBppL", labelWidgetClass, box, NULL, 0);
 
2755
        if (scrn->scrn_defaultbpp)
 
2756
            XmuSnprintf(buf, sizeof(buf), "%d", scrn->scrn_defaultbpp);
 
2757
        else
 
2758
            *buf = '\0';
 
2759
        node->data->screen.defaultBpp =
 
2760
                XtVaCreateManagedWidget("defaultBpp", asciiTextWidgetClass, box,
 
2761
                                        XtNeditType, XawtextEdit,
 
2762
                                        XtNstring, buf,
 
2763
                                        NULL);
 
2764
 
 
2765
        XtCreateManagedWidget("defaultFbBppL", labelWidgetClass, box, NULL, 0);
 
2766
        if (scrn->scrn_defaultfbbpp)
 
2767
            XmuSnprintf(buf, sizeof(buf), "%d", scrn->scrn_defaultfbbpp);
 
2768
        else
 
2769
            *buf = '\0';
 
2770
        node->data->screen.defaultFbBpp =
 
2771
                XtVaCreateManagedWidget("defaultFbBpp", asciiTextWidgetClass, box,
 
2772
                                        XtNeditType, XawtextEdit,
 
2773
                                        XtNstring, buf,
 
2774
                                        NULL);
 
2775
 
 
2776
        XtCreateManagedWidget("monitorL", labelWidgetClass, box, NULL, 0);
 
2777
        str = scrn->scrn_monitor_str ? scrn->scrn_monitor_str : "";
 
2778
        node->data->screen.monitor =
 
2779
                XtVaCreateManagedWidget("monitor", asciiTextWidgetClass, box,
 
2780
                                        XtNeditType, XawtextEdit,
 
2781
                                        XtNstring, str,
 
2782
                                        NULL);
 
2783
 
 
2784
        XtCreateManagedWidget("deviceL", labelWidgetClass, box, NULL, 0);
 
2785
        str = scrn->scrn_device_str ? scrn->scrn_device_str : "";
 
2786
        node->data->screen.device =
 
2787
                XtVaCreateManagedWidget("device", asciiTextWidgetClass, box,
 
2788
                                        XtNeditType, XawtextEdit,
 
2789
                                        XtNstring, str,
 
2790
                                        NULL);
 
2791
 
 
2792
        command = XtVaCreateManagedWidget("videoAdaptor", toggleWidgetClass,
 
2793
                                          tree, XtNstate, True,
 
2794
                                          XtNtreeParent, box, NULL);
 
2795
        adaptor = NewNode(node, command, command, node->node, NULL);
 
2796
        CreateScreenAdaptor(adaptor, scrn->scrn_adaptor_lst);
 
2797
        node->child = adaptor;
 
2798
 
 
2799
        command = XtVaCreateManagedWidget("Display", toggleWidgetClass,
 
2800
                                          tree, XtNstate, True,
 
2801
                                          XtNtreeParent, box, NULL);
 
2802
        display = NewNode(node, command, command, node->node, NULL);
 
2803
        CreateScreenDisplay(display, scrn->scrn_display_lst);
 
2804
        adaptor->next = display;
 
2805
    }
 
2806
    else {
 
2807
        command = XtCreateManagedWidget("new", commandWidgetClass, box,
 
2808
                                        NULL, 0);
 
2809
        XtAddCallback(command, XtNcallback, NewScreenCallback, (XtPointer)node);
 
2810
        label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
2811
                                        XtNeditType, XawtextEdit,
 
2812
                                        NULL);
 
2813
        node->data->screen.text = label;
 
2814
    }
 
2815
    if (XtIsRealized(node->treeParent))
 
2816
        XtRealizeWidget(box);
 
2817
    XtManageChild(box);
 
2818
}
 
2819
 
 
2820
static void
 
2821
NewScreenCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
2822
{
 
2823
    TreeNode *parent, *node = (TreeNode*)user_data;
 
2824
    XF86ConfScreenPtr scrn;
 
2825
    Arg args[1];
 
2826
    char *label;
 
2827
 
 
2828
    XtSetArg(args[0], XtNstring, &label);
 
2829
    XtGetValues(node->data->screen.text, args, 1);
 
2830
    if (*label == '\0')
 
2831
        return;
 
2832
 
 
2833
    parent = node->parent;
 
2834
    DeleteNode(node);
 
2835
    scrn = (XF86ConfScreenPtr)XtCalloc(1, sizeof(XF86ConfScreenRec));
 
2836
    scrn->scrn_identifier = XtNewString(label);
 
2837
    XF86Config->conf_screen_lst =
 
2838
        xf86addScreen(XF86Config->conf_screen_lst, scrn);
 
2839
 
 
2840
    {
 
2841
        TreeNode *lay = layoutTree->child;
 
2842
        Widget sme;
 
2843
 
 
2844
        /* last one is the "new" entry */
 
2845
        while (lay && lay->next != NULL) {
 
2846
            /* Adjacency is the first entry */
 
2847
            TreeNode *adj = lay->child->child;
 
2848
 
 
2849
            while (adj != NULL) {
 
2850
                sme = XtCreateManagedWidget(label, smeBSBObjectClass,
 
2851
                                            adj->data->adjacency.menu, NULL, 0);
 
2852
                XtAddCallback(sme, XtNcallback, adj->next != NULL ?
 
2853
                              AdjacencyMenuCallback : NewAdjacencyCallback,
 
2854
                              (XtPointer)adj);
 
2855
                adj = adj->next;
 
2856
            }
 
2857
            lay = lay->next;
 
2858
        }
 
2859
    }
 
2860
 
 
2861
    CreateScreen(parent, scrn);
 
2862
 
 
2863
    RelayoutTree();
 
2864
}
 
2865
 
 
2866
static void
 
2867
ScreenDestroy(TreeNode *node)
 
2868
{
 
2869
    if (node->data->screen.screen) {
 
2870
        int i;
 
2871
        TreeNode *lay = layoutTree->child;
 
2872
 
 
2873
        /* last one is the "new" entry */
 
2874
        while (lay && lay->next) {
 
2875
            /* Adjacency is the first entry */
 
2876
            TreeNode *adj = lay->child->child;
 
2877
            CompositeWidget composite;
 
2878
 
 
2879
            while (adj) {
 
2880
                TreeNode *next = adj->next;
 
2881
 
 
2882
                composite = (CompositeWidget)adj->data->adjacency.menu;
 
2883
 
 
2884
                for (i = 0; i < composite->composite.num_children; ++i)
 
2885
                    if (strcmp(XtName(composite->composite.children[i]),
 
2886
                               node->data->screen.screen->scrn_identifier) == 0) {
 
2887
                        XtDestroyWidget(composite->composite.children[i]);
 
2888
                        break;
 
2889
                    }
 
2890
 
 
2891
                if (adj->data->adjacency.screen == node->data->screen.screen)
 
2892
                    DeleteNode(adj);
 
2893
 
 
2894
                adj = next;
 
2895
            }
 
2896
 
 
2897
            lay = lay->next;
 
2898
        }
 
2899
 
 
2900
        for (i = 0; i < computer.num_screens; i++)
 
2901
            if (computer.screens[i]->screen == node->data->screen.screen) {
 
2902
                config = computer.screens[i]->widget;
 
2903
                RemoveDeviceCallback(NULL, NULL, NULL);
 
2904
            }
 
2905
 
 
2906
        /* for the case of screens added and removed in the expert dialog */
 
2907
        xf86removeScreen(XF86Config, node->data->screen.screen);
 
2908
    }
 
2909
}
 
2910
 
 
2911
static void
 
2912
ScreenUpdate(TreeNode *node)
 
2913
{
 
2914
    char *str;
 
2915
 
 
2916
    /* defautDepth */
 
2917
    XtVaGetValues(node->data->screen.defaultDepth, XtNstring, &str, NULL);
 
2918
    node->data->screen.screen->scrn_defaultdepth = strtoul(str, NULL, 0);
 
2919
 
 
2920
        /* defautBpp */
 
2921
    XtVaGetValues(node->data->screen.defaultBpp, XtNstring, &str, NULL);
 
2922
    node->data->screen.screen->scrn_defaultbpp = strtoul(str, NULL, 0);
 
2923
 
 
2924
    /* defautFbBpp */
 
2925
    XtVaGetValues(node->data->screen.defaultFbBpp, XtNstring, &str, NULL);
 
2926
    node->data->screen.screen->scrn_defaultfbbpp = strtoul(str, NULL, 0);
 
2927
 
 
2928
 
 
2929
    /* XXX Monitor and Device should be changed to a menu interface */
 
2930
    /* monitor */
 
2931
    XtVaGetValues(node->data->screen.monitor, XtNstring, &str, NULL);
 
2932
    XtFree(node->data->screen.screen->scrn_monitor_str);
 
2933
    if (*str)
 
2934
        node->data->screen.screen->scrn_monitor_str = XtNewString(str);
 
2935
    else
 
2936
        node->data->screen.screen->scrn_monitor_str = NULL;
 
2937
 
 
2938
    /* XXX Monitor and Device should be changed to a menu interface */
 
2939
    /* device */
 
2940
    XtVaGetValues(node->data->screen.device, XtNstring, &str, NULL);
 
2941
    XtFree(node->data->screen.screen->scrn_device_str);
 
2942
    if (*str)
 
2943
        node->data->screen.screen->scrn_device_str = XtNewString(str);
 
2944
    else
 
2945
        node->data->screen.screen->scrn_device_str = NULL;
 
2946
}
 
2947
 
 
2948
static void
 
2949
CreateScreenAdaptor(TreeNode *parent, XF86ConfAdaptorLinkPtr lnk)
 
2950
{
 
2951
    TreeNode *node, *prev;
 
2952
    TreeData *data;
 
2953
 
 
2954
    if ((prev = parent->child) != NULL)
 
2955
        while (prev->next)
 
2956
            prev = prev->next;
 
2957
 
 
2958
    while (lnk) {
 
2959
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
2960
        data->adaptorlink.adaptorlink = lnk;
 
2961
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
2962
        node->destroy = ScreenAdaptorDestroy;
 
2963
        CreateScreenAdaptorField(node, False);
 
2964
        if (parent->child == NULL)
 
2965
            parent->child = node;
 
2966
        else
 
2967
            prev->next = node;
 
2968
        prev = node;
 
2969
        lnk = (XF86ConfAdaptorLinkPtr)(lnk->list.next);
 
2970
    }
 
2971
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
2972
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
2973
    if (parent->child == NULL)
 
2974
        parent->child = node;
 
2975
    else
 
2976
        prev->next = node;
 
2977
    prev = node;
 
2978
    CreateScreenAdaptorField(node, True);
 
2979
}
 
2980
 
 
2981
static void
 
2982
CreateScreenAdaptorField(TreeNode *node, Bool addnew)
 
2983
{
 
2984
    Widget box, command;
 
2985
 
 
2986
    box = XtVaCreateWidget("adaptor", formWidgetClass, tree,
 
2987
                           XtNtreeParent, node->treeParent, NULL);
 
2988
    node->node = box;
 
2989
 
 
2990
    if (!addnew) {
 
2991
        XF86ConfAdaptorLinkPtr lnk = node->data->adaptorlink.adaptorlink;
 
2992
 
 
2993
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
2994
                                        NULL, 0);
 
2995
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
2996
        (void) XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
2997
                                        XtNlabel, lnk->al_adaptor_str, NULL);
 
2998
    }
 
2999
    else {
 
3000
        Widget sme;
 
3001
        XF86ConfVideoAdaptorPtr ptr = XF86Config->conf_videoadaptor_lst;
 
3002
 
 
3003
        command = XtVaCreateManagedWidget("new", menuButtonWidgetClass, box,
 
3004
                                          XtNmenuName, "adaptorMenu", NULL);
 
3005
        node->data->adaptorlink.menu =
 
3006
            XtVaCreatePopupShell("adaptorMenu", simpleMenuWidgetClass, box,
 
3007
                                 XtNleftMargin, 1, XtNrightMargin, 1,
 
3008
                                 XtNtopMargin, 1, XtNbottomMargin, 1,
 
3009
                                 NULL);
 
3010
        while (ptr) {
 
3011
            sme = XtCreateManagedWidget(ptr->va_identifier, smeBSBObjectClass,
 
3012
                                        node->data->adaptorlink.menu, NULL, 0);
 
3013
            XtAddCallback(sme, XtNcallback, NewScreenAdaptorCallback,
 
3014
                          (XtPointer)node);
 
3015
            ptr = (XF86ConfVideoAdaptorPtr)(ptr->list.next);
 
3016
        }
 
3017
    }
 
3018
    if (XtIsRealized(node->treeParent))
 
3019
        XtRealizeWidget(box);
 
3020
    XtManageChild(box);
 
3021
}
 
3022
 
 
3023
/*ARGSUSED*/
 
3024
static void
 
3025
NewScreenAdaptorCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
3026
{
 
3027
    TreeNode *parent, *node = (TreeNode*)user_data;
 
3028
    XF86ConfAdaptorLinkPtr link;
 
3029
    char *ident = XtName(w);
 
3030
 
 
3031
    parent = node->parent;
 
3032
    DeleteNode(node);
 
3033
    link = (XF86ConfAdaptorLinkPtr)XtCalloc(1, sizeof(XF86ConfAdaptorLinkRec));
 
3034
    link->al_adaptor_str = XtNewString(ident);
 
3035
    parent->parent->data->screen.screen->scrn_adaptor_lst =
 
3036
        xf86addScreenAdaptor(parent->parent->data->screen.screen->scrn_adaptor_lst,
 
3037
                             link);
 
3038
 
 
3039
    CreateScreenAdaptor(parent, link);
 
3040
    RelayoutTree();
 
3041
}
 
3042
 
 
3043
/*ARGUSED*/
 
3044
static void
 
3045
ScreenAdaptorDestroy(TreeNode *node)
 
3046
{
 
3047
    if (node->data->adaptorlink.adaptorlink)
 
3048
        xf86removeScreenAdaptorLink(node->parent->parent->data->screen.screen,
 
3049
                                    node->data->adaptorlink.adaptorlink);
 
3050
}
 
3051
 
 
3052
static void
 
3053
CreateScreenDisplay(TreeNode *parent, XF86ConfDisplayPtr dsp)
 
3054
{
 
3055
    TreeNode *node, *prev;
 
3056
    TreeData *data;
 
3057
 
 
3058
    if ((prev = parent->child) != NULL)
 
3059
        while (prev->next)
 
3060
            prev = prev->next;
 
3061
 
 
3062
    while (dsp) {
 
3063
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
3064
        data->display.display = dsp;
 
3065
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
3066
        node->destroy = ScreenDisplayDestroy;
 
3067
        node->update = ScreenDisplayUpdate;
 
3068
        CreateScreenDisplayField(node, False);
 
3069
        if (parent->child == NULL)
 
3070
            parent->child = node;
 
3071
        else
 
3072
            prev->next = node;
 
3073
        prev = node;
 
3074
        dsp = (XF86ConfDisplayPtr)(dsp->list.next);
 
3075
    }
 
3076
    node = NewNode(parent, NULL, NULL, parent->node, NULL);
 
3077
    if (parent->child == NULL)
 
3078
        parent->child = node;
 
3079
    else
 
3080
        prev->next = node;
 
3081
    prev = node;
 
3082
    CreateScreenDisplayField(node, True);
 
3083
}
 
3084
 
 
3085
static void
 
3086
CreateScreenDisplayField(TreeNode *node, Bool addnew)
 
3087
{
 
3088
    Widget box, command;
 
3089
 
 
3090
    box = XtVaCreateWidget("display", formWidgetClass, tree,
 
3091
                           XtNtreeParent, node->treeParent, NULL);
 
3092
    node->node = box;
 
3093
 
 
3094
    if (!addnew) {
 
3095
        char *str, buf[256];
 
3096
        XF86OptionPtr *options;
 
3097
        XF86ConfDisplayPtr dsp = node->data->display.display;
 
3098
        TreeNode *modes;
 
3099
 
 
3100
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
3101
                                        NULL, 0);
 
3102
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
3103
        options = &(dsp->disp_option_lst);
 
3104
        command = XtCreateManagedWidget("options", commandWidgetClass, box,
 
3105
                                        NULL, 0);
 
3106
        XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
 
3107
 
 
3108
        XtCreateManagedWidget("viewportL", labelWidgetClass, box, NULL, 0);
 
3109
        if (dsp->disp_frameX0 != 0 || dsp->disp_frameY0 != 0)
 
3110
            XmuSnprintf(buf, sizeof(buf), "%d %d", dsp->disp_frameX0, dsp->disp_frameY0);
 
3111
        else
 
3112
            *buf = '\0';
 
3113
        node->data->display.viewport =
 
3114
                XtVaCreateManagedWidget("viewport", asciiTextWidgetClass, box,
 
3115
                                        XtNeditType, XawtextEdit,
 
3116
                                        XtNstring, buf, NULL);
 
3117
 
 
3118
        XtCreateManagedWidget("virtualL", labelWidgetClass, box, NULL, 0);
 
3119
        if (dsp->disp_virtualX != 0 || dsp->disp_virtualY != 0)
 
3120
            XmuSnprintf(buf, sizeof(buf), "%d %d", dsp->disp_virtualX, dsp->disp_virtualY);
 
3121
        else
 
3122
            *buf = '\0';
 
3123
        node->data->display.c_virtual =
 
3124
                XtVaCreateManagedWidget("virtual", asciiTextWidgetClass, box,
 
3125
                                        XtNeditType, XawtextEdit,
 
3126
                                        XtNstring, buf, NULL);
 
3127
 
 
3128
        XtCreateManagedWidget("depthL", labelWidgetClass, box, NULL, 0);
 
3129
        if (dsp->disp_depth != 0)
 
3130
            XmuSnprintf(buf, sizeof(buf), "%d", dsp->disp_depth);
 
3131
        else
 
3132
            *buf = '\0';
 
3133
        node->data->display.depth =
 
3134
                XtVaCreateManagedWidget("depth", asciiTextWidgetClass, box,
 
3135
                                        XtNeditType, XawtextEdit,
 
3136
                                        XtNstring, buf, NULL);
 
3137
 
 
3138
        XtCreateManagedWidget("bppL", labelWidgetClass, box, NULL, 0);
 
3139
        if (dsp->disp_bpp != 0)
 
3140
            XmuSnprintf(buf, sizeof(buf), "%d", dsp->disp_bpp);
 
3141
        else
 
3142
            *buf = '\0';
 
3143
        node->data->display.bpp =
 
3144
                XtVaCreateManagedWidget("bpp", asciiTextWidgetClass, box,
 
3145
                                        XtNeditType, XawtextEdit,
 
3146
                                        XtNstring, buf, NULL);
 
3147
 
 
3148
        XtCreateManagedWidget("visualL", labelWidgetClass, box, NULL, 0);
 
3149
        str = dsp->disp_visual != NULL ? dsp->disp_visual : "";
 
3150
        node->data->display.visual =
 
3151
                XtVaCreateManagedWidget("visual", asciiTextWidgetClass, box,
 
3152
                                        XtNeditType, XawtextEdit,
 
3153
                                        XtNstring, str, NULL);
 
3154
 
 
3155
        XtCreateManagedWidget("weightL", labelWidgetClass, box, NULL, 0);
 
3156
        if (dsp->disp_weight.red > 0)
 
3157
            XmuSnprintf(buf, sizeof(buf), "%d %d %d",
 
3158
                        dsp->disp_weight.red, dsp->disp_weight.green, dsp->disp_weight.blue);
 
3159
        else
 
3160
            *buf = '\0';
 
3161
        node->data->display.weight =
 
3162
                XtVaCreateManagedWidget("weight", asciiTextWidgetClass, box,
 
3163
                                        XtNeditType, XawtextEdit,
 
3164
                                        XtNstring, buf, NULL);
 
3165
 
 
3166
        XtCreateManagedWidget("blackL", labelWidgetClass, box, NULL, 0);
 
3167
        if (dsp->disp_black.red >= 0)
 
3168
            XmuSnprintf(buf, sizeof(buf), "0x%04x 0x%04x 0x%04x",
 
3169
                        dsp->disp_black.red, dsp->disp_black.green, dsp->disp_black.blue);
 
3170
        else
 
3171
            *buf = '\0';
 
3172
        node->data->display.black =
 
3173
                XtVaCreateManagedWidget("black", asciiTextWidgetClass, box,
 
3174
                                        XtNeditType, XawtextEdit,
 
3175
                                        XtNstring, buf, NULL);
 
3176
 
 
3177
        XtCreateManagedWidget("whiteL", labelWidgetClass, box, NULL, 0);
 
3178
        if (dsp->disp_white.red >= 0)
 
3179
            XmuSnprintf(buf, sizeof(buf), "0x%04x 0x%04x 0x%04x",
 
3180
                        dsp->disp_white.red, dsp->disp_white.green, dsp->disp_white.blue);
 
3181
        else
 
3182
            *buf = '\0';
 
3183
        node->data->display.white =
 
3184
                XtVaCreateManagedWidget("white", asciiTextWidgetClass, box,
 
3185
                                        XtNeditType, XawtextEdit,
 
3186
                                        XtNstring, buf, NULL);
 
3187
 
 
3188
        command = XtVaCreateManagedWidget("Modes", toggleWidgetClass, tree,
 
3189
                                          XtNstate, True, XtNtreeParent, box,
 
3190
                                          NULL);
 
3191
        modes = NewNode(node, command, command, node->node, NULL);
 
3192
        node->child = modes;
 
3193
        CreateDisplayMode(modes, dsp->disp_mode_lst);
 
3194
    }
 
3195
    else {
 
3196
        command = XtCreateManagedWidget("new", commandWidgetClass, box, NULL, 0);
 
3197
        XtAddCallback(command, XtNcallback, NewScreenDisplayCallback,
 
3198
                     (XtPointer)node);
 
3199
    }
 
3200
    if (XtIsRealized(node->treeParent))
 
3201
        XtRealizeWidget(box);
 
3202
    XtManageChild(box);
 
3203
}
 
3204
 
 
3205
/*ARGSUSED*/
 
3206
static void
 
3207
NewScreenDisplayCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
3208
{
 
3209
    TreeNode *parent, *node = (TreeNode*)user_data;
 
3210
    XF86ConfDisplayPtr dsp;
 
3211
 
 
3212
    parent = node->parent;
 
3213
    DeleteNode(node);
 
3214
    dsp = (XF86ConfDisplayPtr)XtCalloc(1, sizeof(XF86ConfDisplayRec));
 
3215
    dsp->disp_black.red = dsp->disp_black.green = dsp->disp_black.blue =
 
3216
    dsp->disp_white.red = dsp->disp_white.green = dsp->disp_white.blue = -1;
 
3217
    parent->parent->data->screen.screen->scrn_display_lst =
 
3218
        xf86addScreenDisplay(parent->parent->data->screen.screen->scrn_display_lst,
 
3219
                             dsp);
 
3220
 
 
3221
    CreateScreenDisplay(parent, dsp);
 
3222
    RelayoutTree();
 
3223
}
 
3224
 
 
3225
static void
 
3226
ScreenDisplayDestroy(TreeNode *node)
 
3227
{
 
3228
    if (node->data->display.display)
 
3229
        xf86removeScreenDisplay(node->parent->parent->data->screen.screen,
 
3230
                                node->data->display.display);
 
3231
}
 
3232
 
 
3233
static void
 
3234
ScreenDisplayUpdate(TreeNode *node)
 
3235
{
 
3236
    char *str, *tmp;
 
3237
    int x, y;
 
3238
 
 
3239
    /* viewport */
 
3240
    XtVaGetValues(node->data->display.viewport, XtNstring, &str, NULL);
 
3241
    if (sscanf(str, "%d %d", &x, &y) == 2) {
 
3242
        node->data->display.display->disp_frameX0 = x;
 
3243
        node->data->display.display->disp_frameY0 = y;
 
3244
    }
 
3245
 
 
3246
    /* virtual */
 
3247
    XtVaGetValues(node->data->display.c_virtual, XtNstring, &str, NULL);
 
3248
    if (sscanf(str, "%d %d", &x, &y) == 2) {
 
3249
        node->data->display.display->disp_virtualX = x;
 
3250
        node->data->display.display->disp_virtualY = y;
 
3251
    }
 
3252
 
 
3253
    /* depth */
 
3254
    XtVaGetValues(node->data->display.depth, XtNstring, &str, NULL);
 
3255
    node->data->display.display->disp_depth = strtoul(str, NULL, 0);
 
3256
 
 
3257
    /* bpp */
 
3258
    XtVaGetValues(node->data->display.bpp, XtNstring, &str, NULL);
 
3259
    node->data->display.display->disp_bpp = strtoul(str, NULL, 0);
 
3260
 
 
3261
    /* visual */
 
3262
    XtVaGetValues(node->data->display.visual, XtNstring, &str, NULL);
 
3263
    XtFree(node->data->display.display->disp_visual);
 
3264
    if (*str)
 
3265
        node->data->display.display->disp_visual = XtNewString(str);
 
3266
    else
 
3267
        node->data->display.display->disp_visual = NULL;
 
3268
 
 
3269
    /* weight */
 
3270
    XtVaGetValues(node->data->display.weight, XtNstring, &str, NULL);
 
3271
    node->data->display.display->disp_weight.red = strtoul(str, &tmp, 0);
 
3272
    if (str == tmp)
 
3273
        node->data->display.display->disp_weight.red = 0;
 
3274
    else {
 
3275
        str = tmp;
 
3276
        while (isspace(*str))
 
3277
            ++str;
 
3278
        node->data->display.display->disp_weight.green = strtoul(str, &tmp, 0);
 
3279
        if (str != tmp) {
 
3280
            str = tmp;
 
3281
            while (isspace(*str))
 
3282
                ++str;
 
3283
            node->data->display.display->disp_weight.blue = strtoul(str, &tmp, 0);
 
3284
        }
 
3285
    }
 
3286
 
 
3287
    /* black */
 
3288
    XtVaGetValues(node->data->display.black, XtNstring, &str, NULL);
 
3289
    node->data->display.display->disp_black.red = strtoul(str, &tmp, 0);
 
3290
    if (str == tmp)
 
3291
        node->data->display.display->disp_black.red = -1;
 
3292
    else {
 
3293
        str = tmp;
 
3294
        while (isspace(*str))
 
3295
            ++str;
 
3296
        node->data->display.display->disp_black.green = strtoul(str, &tmp, 0);
 
3297
        if (str != tmp) {
 
3298
            str = tmp;
 
3299
            while (isspace(*str))
 
3300
                ++str;
 
3301
            node->data->display.display->disp_black.blue = strtoul(str, &tmp, 0);
 
3302
        }
 
3303
    }
 
3304
 
 
3305
    /* white */
 
3306
    XtVaGetValues(node->data->display.white, XtNstring, &str, NULL);
 
3307
    node->data->display.display->disp_white.red = strtoul(str, &tmp, 0);
 
3308
    if (str == tmp)
 
3309
        node->data->display.display->disp_white.red = -1;
 
3310
    else {
 
3311
        str = tmp;
 
3312
        while (isspace(*str))
 
3313
            ++str;
 
3314
        node->data->display.display->disp_white.green = strtoul(str, &tmp, 0);
 
3315
        if (str != tmp) {
 
3316
            str = tmp;
 
3317
            while (isspace(*str))
 
3318
                ++str;
 
3319
            node->data->display.display->disp_white.blue = strtoul(str, &tmp, 0);
 
3320
        }
 
3321
    }
 
3322
}
 
3323
 
 
3324
static void
 
3325
CreateDisplayMode(TreeNode *parent, XF86ModePtr modes)
 
3326
{
 
3327
    TreeNode *node, *prev;
 
3328
    TreeData *data;
 
3329
 
 
3330
    if ((prev = parent->child) != NULL)
 
3331
        while (prev->next)
 
3332
            prev = prev->next;
 
3333
 
 
3334
    while (modes) {
 
3335
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
3336
        data->mode.mode = modes;
 
3337
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
3338
        node->destroy = DisplayModeDestroy;
 
3339
        CreateDisplayModeField(node, False);
 
3340
        if (parent->child == NULL)
 
3341
            parent->child = node;
 
3342
        else
 
3343
            prev->next = node;
 
3344
        prev = node;
 
3345
        modes = (XF86ModePtr)(modes->list.next);
 
3346
    }
 
3347
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
3348
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
3349
    if (parent->child == NULL)
 
3350
        parent->child = node;
 
3351
    else
 
3352
        prev->next = node;
 
3353
    prev = node;
 
3354
    CreateDisplayModeField(node, True);
 
3355
}
 
3356
 
 
3357
static void
 
3358
CreateDisplayModeField(TreeNode *node, Bool addnew)
 
3359
{
 
3360
    Widget box, command, text;
 
3361
 
 
3362
    box = XtVaCreateWidget("mode", formWidgetClass, tree,
 
3363
                           XtNtreeParent, node->treeParent, NULL);
 
3364
    node->node = box;
 
3365
    if (!addnew) {
 
3366
        XF86ModePtr mode = node->data->mode.mode;
 
3367
 
 
3368
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
3369
                                        NULL, 0);
 
3370
        XtAddCallback(command, XtNcallback, DestroyCallback,
 
3371
                      (XtPointer)node);
 
3372
        text = XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
3373
                                       XtNlabel, mode->mode_name, NULL);
 
3374
    }
 
3375
    else {
 
3376
        command = XtCreateManagedWidget("new", commandWidgetClass, box, NULL, 0);
 
3377
        XtAddCallback(command, XtNcallback, NewDisplayModeCallback,
 
3378
                      (XtPointer)node);
 
3379
        text = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
3380
                                       XtNeditType, XawtextEdit, NULL);
 
3381
    }
 
3382
    node->data->mode.text = text;
 
3383
    if (node->treeParent && XtIsRealized(node->treeParent))
 
3384
        XtRealizeWidget(box);
 
3385
    XtManageChild(box);
 
3386
}
 
3387
 
 
3388
/*ARGSUSED*/
 
3389
static void
 
3390
NewDisplayModeCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
3391
{
 
3392
    TreeNode *parent, *node = (TreeNode*)user_data;
 
3393
    XF86ModePtr mode;
 
3394
    Arg args[1];
 
3395
    char *ident;
 
3396
 
 
3397
    XtSetArg(args[0], XtNstring, &ident);
 
3398
    XtGetValues(node->data->mode.text, args, 1);
 
3399
    if (*ident == '\0')
 
3400
        return;
 
3401
 
 
3402
    parent = node->parent;
 
3403
    DeleteNode(node);
 
3404
    mode = (XF86ModePtr)XtCalloc(1, sizeof(XF86ModeRec));
 
3405
    mode->mode_name = XtNewString(ident);
 
3406
    parent->parent->data->display.display->disp_mode_lst =
 
3407
        xf86addDisplayMode(parent->parent->data->display.display->disp_mode_lst,
 
3408
                           mode);
 
3409
 
 
3410
    CreateDisplayMode(parent, mode);
 
3411
    RelayoutTree();
 
3412
}
 
3413
 
 
3414
/*ARGUSED*/
 
3415
static void
 
3416
DisplayModeDestroy(TreeNode *node)
 
3417
{
 
3418
    if (node->data->mode.mode)
 
3419
        xf86removeDisplayMode(node->parent->parent->data->display.display,
 
3420
                              node->data->mode.mode);
 
3421
}
 
3422
 
 
3423
/* Input */
 
3424
static void
 
3425
CreateInput(TreeNode *parent, XF86ConfInputPtr input)
 
3426
{
 
3427
    TreeNode *prev, *node;
 
3428
    TreeData *data;
 
3429
 
 
3430
    if ((prev = parent->child) != NULL)
 
3431
        while (prev->next)
 
3432
            prev = prev->next;
 
3433
 
 
3434
    while (input) {
 
3435
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
3436
        data->input.input = input;
 
3437
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
3438
        node->destroy = InputDestroy;
 
3439
        node->update = InputUpdate;
 
3440
        CreateInputField(node, False);
 
3441
        if (parent->child == NULL)
 
3442
            parent->child = node;
 
3443
        else
 
3444
            prev->next = node;
 
3445
        prev = node;
 
3446
        input = (XF86ConfInputPtr)(input->list.next);
 
3447
    }
 
3448
 
 
3449
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
3450
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
3451
    CreateInputField(node, True);
 
3452
    if (parent->child == NULL)
 
3453
        parent->child = node;
 
3454
    else
 
3455
        prev->next = node;
 
3456
}
 
3457
 
 
3458
static void
 
3459
CreateInputField(TreeNode *node, Bool addnew)
 
3460
{
 
3461
    Widget box, command;
 
3462
 
 
3463
    box = XtVaCreateWidget("input", formWidgetClass, tree,
 
3464
                           XtNtreeParent, node->treeParent, NULL);
 
3465
    node->node = box;
 
3466
 
 
3467
    if (!addnew) {
 
3468
        char *str;
 
3469
        XF86OptionPtr *options;
 
3470
        XF86ConfInputPtr inp = node->data->input.input;
 
3471
 
 
3472
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
3473
                                        NULL, 0);
 
3474
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
3475
        options = &(inp->inp_option_lst);
 
3476
        command = XtCreateManagedWidget("options", commandWidgetClass, box,
 
3477
                                        NULL, 0);
 
3478
        XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
 
3479
        XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
3480
                                XtNlabel, inp->inp_identifier, NULL);
 
3481
 
 
3482
        XtCreateManagedWidget("driverL", labelWidgetClass, box, NULL, 0);
 
3483
        str = inp->inp_driver != NULL ? inp->inp_driver : "";
 
3484
        node->data->input.text =
 
3485
                XtVaCreateManagedWidget("driver", asciiTextWidgetClass, box,
 
3486
                                        XtNeditType, XawtextEdit,
 
3487
                                        XtNstring, str, NULL);
 
3488
    }
 
3489
    else {
 
3490
        command = XtCreateManagedWidget("new", commandWidgetClass, box, NULL, 0);
 
3491
        XtAddCallback(command, XtNcallback, NewInputCallback,
 
3492
                     (XtPointer)node);
 
3493
        node->data->input.text =
 
3494
                XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
3495
                                        XtNeditType, XawtextEdit, NULL);
 
3496
    }
 
3497
    if (XtIsRealized(node->treeParent))
 
3498
        XtRealizeWidget(box);
 
3499
    XtManageChild(box);
 
3500
}
 
3501
 
 
3502
/*ARGSUSED*/
 
3503
static void
 
3504
NewInputCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
3505
{
 
3506
    TreeNode *parent, *node = (TreeNode*)user_data;
 
3507
    XF86ConfInputPtr input;
 
3508
    Arg args[1];
 
3509
    char *ident;
 
3510
 
 
3511
    XtSetArg(args[0], XtNstring, &ident);
 
3512
    XtGetValues(node->data->input.text, args, 1);
 
3513
    if (*ident == '\0')
 
3514
        return;
 
3515
 
 
3516
    parent = node->parent;
 
3517
    DeleteNode(node);
 
3518
    input = (XF86ConfInputPtr)XtCalloc(1, sizeof(XF86ConfInputRec));
 
3519
    input->inp_identifier = XtNewString(ident);
 
3520
    XF86Config->conf_input_lst =
 
3521
        xf86addInput(XF86Config->conf_input_lst, input);
 
3522
 
 
3523
    {
 
3524
        TreeNode *lay = layoutTree->child;
 
3525
        Widget sme;
 
3526
 
 
3527
        /* last one is the "new" entry */
 
3528
        while (lay && lay->next != NULL) {
 
3529
            /* Inputref is the second entry */
 
3530
            TreeNode *iref = lay->child->next->child;
 
3531
 
 
3532
            while (iref && iref->next)
 
3533
                iref = iref->next;
 
3534
            sme = XtCreateManagedWidget(ident, smeBSBObjectClass,
 
3535
                                        iref->data->inputref.menu, NULL, 0);
 
3536
            XtAddCallback(sme, XtNcallback, NewInputrefCallback,
 
3537
                          (XtPointer)iref);
 
3538
            lay = lay->next;
 
3539
        }
 
3540
    }
 
3541
 
 
3542
    CreateInput(parent, input);
 
3543
    RelayoutTree();
 
3544
}
 
3545
 
 
3546
/*ARGUSED*/
 
3547
static void
 
3548
InputDestroy(TreeNode *node)
 
3549
{
 
3550
    if (node->data->input.input) {
 
3551
        int i;
 
3552
        TreeNode *lay = layoutTree->child;
 
3553
 
 
3554
        /* last one is the "new" entry */
 
3555
        while (lay && lay->next) {
 
3556
            /* Inputref is the second entry */
 
3557
            TreeNode *iref = lay->child->next->child;
 
3558
            CompositeWidget composite;
 
3559
 
 
3560
            while (iref && iref->next) {
 
3561
                TreeNode *next = iref->next;
 
3562
 
 
3563
                if (iref && strcmp(iref->data->inputref.inputref->iref_inputdev_str,
 
3564
                                  node->data->input.input->inp_identifier) == 0)
 
3565
                    DeleteNode(iref);
 
3566
                iref = next;
 
3567
            }
 
3568
 
 
3569
            composite = (CompositeWidget)iref->data->inputref.menu;
 
3570
 
 
3571
            for (i = 0; i < composite->composite.num_children; ++i)
 
3572
                if (strcmp(XtName(composite->composite.children[i]),
 
3573
                           node->data->input.input->inp_identifier) == 0)
 
3574
                    XtDestroyWidget(composite->composite.children[i]);
 
3575
 
 
3576
            lay = lay->next;
 
3577
        }
 
3578
 
 
3579
        for (i = 0; i < computer.num_devices; i++)
 
3580
            if ((XF86ConfInputPtr)(computer.devices[i]->config) ==
 
3581
                node->data->input.input) {
 
3582
                config = computer.devices[i]->widget;
 
3583
                RemoveDeviceCallback(NULL, NULL, NULL);
 
3584
            }
 
3585
    }
 
3586
}
 
3587
 
 
3588
static void
 
3589
InputUpdate(TreeNode *node)
 
3590
{
 
3591
    char *str;
 
3592
 
 
3593
    /* vendor */
 
3594
    XtVaGetValues(node->data->input.text, XtNstring, &str, NULL);
 
3595
    XtFree(node->data->input.input->inp_driver);
 
3596
    if (*str)
 
3597
        node->data->input.input->inp_driver = XtNewString(str);
 
3598
    else
 
3599
        node->data->input.input->inp_driver = NULL;
 
3600
}
 
3601
 
 
3602
/* Layout */
 
3603
static void
 
3604
CreateLayout(TreeNode *parent, XF86ConfLayoutPtr lay)
 
3605
{
 
3606
    TreeNode *prev, *node;
 
3607
    TreeData *data;
 
3608
 
 
3609
    if ((prev = parent->child) != NULL)
 
3610
        while (prev->next)
 
3611
            prev = prev->next;
 
3612
 
 
3613
    while (lay) {
 
3614
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
3615
        data->layout.layout = lay;
 
3616
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
3617
        node->destroy = LayoutDestroy;
 
3618
        CreateLayoutField(node, False);
 
3619
        if (parent->child == NULL)
 
3620
            parent->child = node;
 
3621
        else
 
3622
            prev->next = node;
 
3623
        prev = node;
 
3624
        lay = (XF86ConfLayoutPtr)(lay->list.next);
 
3625
    }
 
3626
 
 
3627
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
3628
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
3629
    CreateLayoutField(node, True);
 
3630
    if (parent->child == NULL)
 
3631
        parent->child = node;
 
3632
    else
 
3633
        prev->next = node;
 
3634
}
 
3635
 
 
3636
static void
 
3637
CreateLayoutField(TreeNode *node, Bool addnew)
 
3638
{
 
3639
    Widget box, command, label;
 
3640
 
 
3641
    box = XtVaCreateWidget("layout", formWidgetClass, tree,
 
3642
                           XtNtreeParent, node->treeParent, NULL);
 
3643
    node->node = box;
 
3644
 
 
3645
    if (!addnew) {
 
3646
        TreeNode *adjacency, *inputref;
 
3647
        XF86OptionPtr *options;
 
3648
        XF86ConfLayoutPtr lay = node->data->layout.layout;
 
3649
 
 
3650
        options = &(lay->lay_option_lst);
 
3651
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
3652
                                        NULL, 0);
 
3653
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
3654
        command = XtCreateManagedWidget("options", commandWidgetClass, box,
 
3655
                                        NULL, 0);
 
3656
        XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
 
3657
        label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
3658
                                        XtNlabel, lay->lay_identifier, NULL);
 
3659
 
 
3660
        command = XtVaCreateManagedWidget("Adjacency", toggleWidgetClass, tree,
 
3661
                                          XtNstate, True, XtNtreeParent, box,
 
3662
                                          NULL);
 
3663
        adjacency = NewNode(node, command, command, box, NULL);
 
3664
        node->child = adjacency;
 
3665
        CreateAdjacency(adjacency, lay->lay_adjacency_lst);
 
3666
 
 
3667
        command = XtVaCreateManagedWidget("Inputref", toggleWidgetClass, tree,
 
3668
                                          XtNstate, True, XtNtreeParent, box,
 
3669
                                          NULL);
 
3670
        inputref = NewNode(node, command, command, box, NULL);
 
3671
        adjacency->next = inputref;
 
3672
        CreateInputref(inputref, lay->lay_input_lst);
 
3673
    }
 
3674
    else {
 
3675
        command = XtCreateManagedWidget("new", commandWidgetClass, box,
 
3676
                                        NULL, 0);
 
3677
        XtAddCallback(command, XtNcallback, NewLayoutCallback, (XtPointer)node);
 
3678
        label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
3679
                                        XtNeditType, XawtextEdit,
 
3680
                                        NULL);
 
3681
        node->data->layout.text = label;
 
3682
    }
 
3683
    if (XtIsRealized(node->treeParent))
 
3684
        XtRealizeWidget(box);
 
3685
    XtManageChild(box);
 
3686
}
 
3687
 
 
3688
/*ARGUSED*/
 
3689
static void
 
3690
LayoutDestroy(TreeNode *node)
 
3691
{
 
3692
    if (node->data->layout.layout)
 
3693
        xf86removeLayout(XF86Config, node->data->layout.layout);
 
3694
}
 
3695
 
 
3696
/*ARGSUSED*/
 
3697
static void
 
3698
NewLayoutCallback(Widget unused, XtPointer user_data, XtPointer call_data)
 
3699
{
 
3700
    TreeNode *parent, *node = (TreeNode*)user_data;
 
3701
    XF86ConfLayoutPtr lay;
 
3702
    Arg args[1];
 
3703
    char *label;
 
3704
 
 
3705
    XtSetArg(args[0], XtNstring, &label);
 
3706
    XtGetValues(node->data->layout.text, args, 1);
 
3707
    if (*label == '\0')
 
3708
        return;
 
3709
 
 
3710
    parent = node->parent;
 
3711
    DeleteNode(node);
 
3712
    lay = (XF86ConfLayoutPtr)XtCalloc(1, sizeof(XF86ConfLayoutRec));
 
3713
    lay->lay_identifier = XtNewString(label);
 
3714
    XF86Config->conf_layout_lst = xf86addLayout(XF86Config->conf_layout_lst, lay);
 
3715
 
 
3716
    CreateLayout(parent, lay);
 
3717
    RelayoutTree();
 
3718
}
 
3719
 
 
3720
static void
 
3721
CreateAdjacency(TreeNode *parent, XF86ConfAdjacencyPtr adj)
 
3722
{
 
3723
    TreeNode *prev, *node;
 
3724
    TreeData *data;
 
3725
 
 
3726
    if ((prev = parent->child) != NULL)
 
3727
        while (prev->next)
 
3728
            prev = prev->next;
 
3729
 
 
3730
    while (adj) {
 
3731
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
3732
        data->adjacency.screen = adj ? adj->adj_screen : NULL;
 
3733
        data->adjacency.adjacency = adj;
 
3734
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
3735
        node->destroy = AdjacencyDestroy;
 
3736
        CreateAdjacencyField(node, False);
 
3737
        if (parent->child == NULL)
 
3738
            parent->child = node;
 
3739
        else
 
3740
            prev->next = node;
 
3741
        prev = node;
 
3742
        adj = (XF86ConfAdjacencyPtr)(adj->list.next);
 
3743
    }
 
3744
 
 
3745
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
3746
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
3747
    CreateAdjacencyField(node, True);
 
3748
    if (parent->child == NULL)
 
3749
        parent->child = node;
 
3750
    else
 
3751
        prev->next = node;
 
3752
}
 
3753
 
 
3754
static void
 
3755
CreateAdjacencyField(TreeNode *node, Bool addnew)
 
3756
{
 
3757
    Widget box, command, sme;
 
3758
    XF86ConfScreenPtr ptr = XF86Config->conf_screen_lst;
 
3759
 
 
3760
    box = XtVaCreateWidget("adjacency", formWidgetClass, tree,
 
3761
                           XtNtreeParent, node->treeParent, NULL);
 
3762
    node->node = box;
 
3763
 
 
3764
    node->data->adjacency.menu =
 
3765
        XtVaCreatePopupShell("screenMenu", simpleMenuWidgetClass, box,
 
3766
                             XtNleftMargin, 1, XtNrightMargin, 1,
 
3767
                             XtNtopMargin, 1, XtNbottomMargin, 1,
 
3768
                             NULL);
 
3769
    while (ptr) {
 
3770
        sme = XtCreateManagedWidget(ptr->scrn_identifier, smeBSBObjectClass,
 
3771
                                    node->data->adjacency.menu, NULL, 0);
 
3772
        XtAddCallback(sme, XtNcallback, !addnew ?
 
3773
                      AdjacencyMenuCallback : NewAdjacencyCallback,
 
3774
                      (XtPointer)node);
 
3775
        ptr = (XF86ConfScreenPtr)(ptr->list.next);
 
3776
    }
 
3777
 
 
3778
    if (!addnew) {
 
3779
        char buf[32];
 
3780
        Cardinal width, height;
 
3781
        Widget left, right, above, below, relative, absolute;
 
3782
        XF86ConfAdjacencyPtr adj = node->data->adjacency.adjacency;
 
3783
 
 
3784
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
3785
                                        NULL, 0);
 
3786
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
3787
        (void) XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
3788
                                        XtNlabel, adj->adj_screen->scrn_identifier,
 
3789
                                        NULL);
 
3790
 
 
3791
        XtCreateManagedWidget("scrnumL", labelWidgetClass, box, NULL, 0);
 
3792
        if (adj->adj_scrnum >= 0)
 
3793
            XmuSnprintf(buf, sizeof(buf), "%d", adj->adj_scrnum);
 
3794
        else
 
3795
            *buf = 0;
 
3796
        node->data->adjacency.scrnum =
 
3797
                XtVaCreateManagedWidget("scrnum", asciiTextWidgetClass, box,
 
3798
                                        XtNeditType, XawtextEdit,
 
3799
                                        XtNstring, buf, NULL);
 
3800
        above = XtVaCreateManagedWidget("above", toggleWidgetClass, box,
 
3801
                                XtNstate, adj->adj_where == CONF_ADJ_ABOVE ?
 
3802
                                True : False, NULL);
 
3803
        XtAddCallback(above, XtNcallback, AdjacencyToggleCallback, (XtPointer)node);
 
3804
        left = XtVaCreateManagedWidget("leftOf", toggleWidgetClass, box,
 
3805
                                XtNradioGroup, above,
 
3806
                                XtNstate, adj->adj_where == CONF_ADJ_LEFTOF ?
 
3807
                                True : False, NULL);
 
3808
        XtAddCallback(left, XtNcallback, AdjacencyToggleCallback, (XtPointer)node);
 
3809
 
 
3810
        node->data->adjacency.button =
 
3811
            XtVaCreateManagedWidget("screen", menuButtonWidgetClass, box,
 
3812
                                    XtNmenuName, "screenMenu", NULL);
 
3813
 
 
3814
        right = XtVaCreateManagedWidget("rightOf", toggleWidgetClass, box,
 
3815
                                XtNradioGroup, left,
 
3816
                                XtNstate, adj->adj_where == CONF_ADJ_RIGHTOF ?
 
3817
                                True : False, NULL);
 
3818
        XtAddCallback(right, XtNcallback, AdjacencyToggleCallback, (XtPointer)node);
 
3819
        below = XtVaCreateManagedWidget("below", toggleWidgetClass, box,
 
3820
                                XtNradioGroup, right,
 
3821
                                XtNstate, adj->adj_where == CONF_ADJ_BELOW ?
 
3822
                                True : False, NULL);
 
3823
        XtAddCallback(below, XtNcallback, AdjacencyToggleCallback, (XtPointer)node);
 
3824
        relative = XtVaCreateManagedWidget("relative", toggleWidgetClass, box,
 
3825
                                XtNradioGroup, below,
 
3826
                                XtNstate, adj->adj_where == CONF_ADJ_RELATIVE ?
 
3827
                                True : False, NULL);
 
3828
        XtAddCallback(relative, XtNcallback, AdjacencyToggleCallback, (XtPointer)node);
 
3829
        absolute = XtVaCreateManagedWidget("absolute", toggleWidgetClass, box,
 
3830
                                XtNradioGroup, relative,
 
3831
                                XtNstate, adj->adj_where == CONF_ADJ_ABSOLUTE ?
 
3832
                                True : False, NULL);
 
3833
        XtAddCallback(absolute, XtNcallback, AdjacencyToggleCallback, (XtPointer)node);
 
3834
 
 
3835
        XtCreateManagedWidget("adjxL", labelWidgetClass, box, NULL, 0);
 
3836
        XmuSnprintf(buf, sizeof(buf), "%d", adj->adj_x);
 
3837
        node->data->adjacency.adjx =
 
3838
                XtVaCreateManagedWidget("adjx", asciiTextWidgetClass, box,
 
3839
                                        XtNeditType, XawtextEdit,
 
3840
                                        XtNstring, buf, NULL);
 
3841
 
 
3842
        XtCreateManagedWidget("adjyL", labelWidgetClass, box, NULL, 0);
 
3843
        XmuSnprintf(buf, sizeof(buf), "%d", adj->adj_y);
 
3844
        node->data->adjacency.adjy =
 
3845
                XtVaCreateManagedWidget("adjy", asciiTextWidgetClass, box,
 
3846
                                        XtNeditType, XawtextEdit,
 
3847
                                        XtNstring, buf, NULL);
 
3848
 
 
3849
        XtVaGetValues(node->data->adjacency.button, XtNwidth, &width,
 
3850
                      XtNheight, &height, NULL);
 
3851
        if (adj->adj_where > CONF_ADJ_ABSOLUTE &&
 
3852
            adj->adj_where <= CONF_ADJ_RELATIVE)
 
3853
            XtVaSetValues(node->data->adjacency.button, XtNlabel,
 
3854
                          adj->adj_refscreen, XtNwidth, width,
 
3855
                          XtNheight, height, NULL);
 
3856
        else
 
3857
            XtVaSetValues(node->data->adjacency.button, XtNlabel, "",
 
3858
                          XtNwidth, width, XtNheight, height, NULL);
 
3859
    }
 
3860
    else
 
3861
        XtVaCreateManagedWidget("new", menuButtonWidgetClass, box,
 
3862
                                XtNmenuName, "screenMenu", NULL);
 
3863
 
 
3864
    if (XtIsRealized(node->treeParent))
 
3865
        XtRealizeWidget(box);
 
3866
    XtManageChild(box);
 
3867
}
 
3868
 
 
3869
static void
 
3870
AdjacencyDestroy(TreeNode *node)
 
3871
{
 
3872
    if (node->data->adjacency.adjacency)
 
3873
        xf86removeAdjacency(node->parent->parent->data->layout.layout,
 
3874
                            node->data->adjacency.adjacency);
 
3875
}
 
3876
 
 
3877
/*ARGSUSED*/
 
3878
static void
 
3879
NewAdjacencyCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
3880
{
 
3881
    TreeNode *parent, *node = (TreeNode*)user_data;
 
3882
    XF86ConfAdjacencyPtr adj;
 
3883
    char *ident = XtName(w);
 
3884
 
 
3885
    parent = node->parent;
 
3886
    DeleteNode(node);
 
3887
    adj = (XF86ConfAdjacencyPtr)XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
 
3888
    adj->adj_screen = xf86findScreen(ident, XF86Config->conf_screen_lst);
 
3889
    if (adj->adj_screen)
 
3890
        adj->adj_screen_str = XtNewString(adj->adj_screen->scrn_identifier);
 
3891
    parent->parent->data->layout.layout->lay_adjacency_lst =
 
3892
        xf86addAdjacency(parent->parent->data->layout.layout->lay_adjacency_lst,
 
3893
                         adj);
 
3894
 
 
3895
    CreateAdjacency(parent, adj);
 
3896
    RelayoutTree();
 
3897
}
 
3898
 
 
3899
/*ARGUSED*/
 
3900
static void
 
3901
AdjacencyMenuCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
3902
{
 
3903
    TreeNode *node = (TreeNode*)user_data;
 
3904
    XF86ConfAdjacencyPtr adj = node->data->adjacency.adjacency;
 
3905
 
 
3906
    XtFree(adj->adj_refscreen);
 
3907
    adj->adj_refscreen = XtNewString(XtName(w));
 
3908
    XtVaSetValues(node->data->adjacency.button, XtNlabel, XtName(w), NULL);
 
3909
}
 
3910
 
 
3911
static void
 
3912
AdjacencyToggleCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
3913
{
 
3914
    TreeNode *node = (TreeNode*)user_data;
 
3915
    XF86ConfAdjacencyPtr adj = node->data->adjacency.adjacency;
 
3916
    char *x, *y;
 
3917
 
 
3918
    if ((Bool)(long)call_data == False)
 
3919
        return;
 
3920
 
 
3921
    XtVaGetValues(node->data->adjacency.adjx, XtNstring, &x, NULL);
 
3922
    XtVaGetValues(node->data->adjacency.adjy, XtNstring, &y, NULL);
 
3923
 
 
3924
    adj->adj_x = strtol(x, NULL, 0);
 
3925
    adj->adj_y = strtol(y, NULL, 0);
 
3926
 
 
3927
    if (strcmp(XtName(w), "absolute") == 0) {
 
3928
    XtVaSetValues(node->data->adjacency.button, XtNlabel, "", NULL);
 
3929
        adj->adj_where = CONF_ADJ_ABSOLUTE;
 
3930
        return;
 
3931
    }
 
3932
    if (strcmp(XtName(w), "relative") == 0)
 
3933
        adj->adj_where = CONF_ADJ_RELATIVE;
 
3934
    else if (strcmp(XtName(w), "leftOf") == 0)
 
3935
        adj->adj_where = CONF_ADJ_LEFTOF;
 
3936
    else if (strcmp(XtName(w), "rightOf") == 0)
 
3937
        adj->adj_where = CONF_ADJ_RIGHTOF;
 
3938
    else if (strcmp(XtName(w), "above") == 0)
 
3939
        adj->adj_where = CONF_ADJ_ABOVE;
 
3940
    else if (strcmp(XtName(w), "below") == 0)
 
3941
        adj->adj_where = CONF_ADJ_BELOW;
 
3942
}
 
3943
 
 
3944
/* Inputref */
 
3945
static void
 
3946
CreateInputref(TreeNode *parent, XF86ConfInputrefPtr input)
 
3947
{
 
3948
    TreeNode *prev, *node;
 
3949
    TreeData *data;
 
3950
 
 
3951
    if ((prev = parent->child) != NULL)
 
3952
        while (prev->next)
 
3953
            prev = prev->next;
 
3954
 
 
3955
    while (input) {
 
3956
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
3957
        data->inputref.inputref = input;
 
3958
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
3959
        node->destroy = InputrefDestroy;
 
3960
        CreateInputrefField(node, False);
 
3961
        if (parent->child == NULL)
 
3962
            parent->child = node;
 
3963
        else
 
3964
            prev->next = node;
 
3965
        prev = node;
 
3966
        input = (XF86ConfInputrefPtr)(input->list.next);
 
3967
    }
 
3968
 
 
3969
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
3970
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
3971
    CreateInputrefField(node, True);
 
3972
    if (parent->child == NULL)
 
3973
        parent->child = node;
 
3974
    else
 
3975
        prev->next = node;
 
3976
}
 
3977
 
 
3978
static void
 
3979
CreateInputrefField(TreeNode *node, Bool addnew)
 
3980
{
 
3981
    Widget box, command;
 
3982
 
 
3983
    box = XtVaCreateWidget("inputref", formWidgetClass, tree,
 
3984
                           XtNtreeParent, node->treeParent, NULL);
 
3985
    node->node = box;
 
3986
 
 
3987
    if (!addnew) {
 
3988
        XF86OptionPtr *options;
 
3989
        XF86ConfInputrefPtr inp = node->data->inputref.inputref;
 
3990
 
 
3991
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
3992
                                        NULL, 0);
 
3993
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
3994
        options = &(inp->iref_option_lst);
 
3995
        command = XtCreateManagedWidget("options", commandWidgetClass, box,
 
3996
                                        NULL, 0);
 
3997
        XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
 
3998
        XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
3999
                                XtNlabel, inp->iref_inputdev_str, NULL);
 
4000
    }
 
4001
    else {
 
4002
        Widget sme;
 
4003
        XF86ConfInputPtr ptr = XF86Config->conf_input_lst;
 
4004
 
 
4005
        XtVaCreateManagedWidget("new", menuButtonWidgetClass, box,
 
4006
                                XtNmenuName, "inputMenu", NULL);
 
4007
        node->data->inputref.menu =
 
4008
            XtVaCreatePopupShell("inputMenu", simpleMenuWidgetClass, box,
 
4009
                                 XtNleftMargin, 1, XtNrightMargin, 1,
 
4010
                                 XtNtopMargin, 1, XtNbottomMargin, 1,
 
4011
                                 NULL);
 
4012
 
 
4013
        while (ptr) {
 
4014
            sme = XtCreateManagedWidget(ptr->inp_identifier, smeBSBObjectClass,
 
4015
                                        node->data->inputref.menu, NULL, 0);
 
4016
            XtAddCallback(sme, XtNcallback, NewInputrefCallback,
 
4017
                          (XtPointer)node);
 
4018
            ptr = (XF86ConfInputPtr)(ptr->list.next);
 
4019
        }
 
4020
    }
 
4021
    if (XtIsRealized(node->treeParent))
 
4022
        XtRealizeWidget(box);
 
4023
    XtManageChild(box);
 
4024
}
 
4025
 
 
4026
/*ARGSUSED*/
 
4027
static void
 
4028
NewInputrefCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
4029
{
 
4030
    TreeNode *parent, *node = (TreeNode*)user_data;
 
4031
    XF86ConfInputrefPtr input;
 
4032
    char *ident = XtName(w);
 
4033
 
 
4034
    parent = node->parent;
 
4035
    DeleteNode(node);
 
4036
    input = (XF86ConfInputrefPtr)XtCalloc(1, sizeof(XF86ConfInputrefRec));
 
4037
    input->iref_inputdev_str = XtNewString(ident);
 
4038
    parent->parent->data->layout.layout->lay_input_lst =
 
4039
        xf86addInputref(parent->parent->data->layout.layout->lay_input_lst, input);
 
4040
 
 
4041
    CreateInputref(parent, input);
 
4042
    RelayoutTree();
 
4043
}
 
4044
 
 
4045
/*ARGUSED*/
 
4046
static void
 
4047
InputrefDestroy(TreeNode *node)
 
4048
{
 
4049
    if (node->data->inputref.inputref)
 
4050
        xf86removeInputRef(node->parent->parent->data->layout.layout, node->data->inputref.inputref->iref_inputdev);
 
4051
}
 
4052
 
 
4053
/* Vendor */
 
4054
static void
 
4055
CreateVendor(TreeNode *parent, XF86ConfVendorPtr vendor)
 
4056
{
 
4057
    TreeNode *prev, *node;
 
4058
    TreeData *data;
 
4059
 
 
4060
    if ((prev = parent->child) != NULL)
 
4061
        while (prev->next)
 
4062
            prev = prev->next;
 
4063
 
 
4064
    while (vendor) {
 
4065
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
4066
        data->vendor.vendor = vendor;
 
4067
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
4068
        node->destroy = VendorDestroy;
 
4069
        CreateVendorField(node, False);
 
4070
        if (parent->child == NULL)
 
4071
            parent->child = node;
 
4072
        else
 
4073
            prev->next = node;
 
4074
        prev = node;
 
4075
        vendor = (XF86ConfVendorPtr)(vendor->list.next);
 
4076
    }
 
4077
 
 
4078
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
4079
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
4080
    CreateVendorField(node, True);
 
4081
    if (parent->child == NULL)
 
4082
        parent->child = node;
 
4083
    else
 
4084
        prev->next = node;
 
4085
}
 
4086
 
 
4087
static void
 
4088
CreateVendorField(TreeNode *node, Bool addnew)
 
4089
{
 
4090
    Widget box, command;
 
4091
 
 
4092
    box = XtVaCreateWidget("vendor", formWidgetClass, tree,
 
4093
                           XtNtreeParent, node->treeParent, NULL);
 
4094
    node->node = box;
 
4095
 
 
4096
    if (!addnew) {
 
4097
        TreeNode *sub;
 
4098
        XF86OptionPtr *options;
 
4099
        XF86ConfVendorPtr vendor = node->data->vendor.vendor;
 
4100
 
 
4101
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
4102
                                        NULL, 0);
 
4103
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
4104
        options = &(vendor->vnd_option_lst);
 
4105
        command = XtCreateManagedWidget("options", commandWidgetClass, box,
 
4106
                                        NULL, 0);
 
4107
        XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
 
4108
        XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
4109
                                XtNlabel, vendor->vnd_identifier, NULL);
 
4110
 
 
4111
        command = XtVaCreateManagedWidget("VendSub", toggleWidgetClass, tree,
 
4112
                                          XtNstate, True,
 
4113
                                          XtNtreeParent, box,
 
4114
                                          NULL);
 
4115
        sub = NewNode(node, command, command, box, NULL);
 
4116
        node->child = sub;
 
4117
        CreateVendorSub(sub, vendor->vnd_sub_lst);
 
4118
    }
 
4119
    else {
 
4120
        command = XtCreateManagedWidget("new", commandWidgetClass, box,
 
4121
                                        NULL, 0);
 
4122
        XtAddCallback(command, XtNcallback, NewVendorCallback, (XtPointer)node);
 
4123
        node->data->vendor.text =
 
4124
            XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
4125
                                    XtNeditType, XawtextEdit, NULL);
 
4126
    }
 
4127
    if (XtIsRealized(node->treeParent))
 
4128
        XtRealizeWidget(box);
 
4129
    XtManageChild(box);
 
4130
}
 
4131
 
 
4132
static void
 
4133
VendorDestroy(TreeNode *node)
 
4134
{
 
4135
    if (node->data->vendor.vendor)
 
4136
        xf86removeVendor(XF86Config, node->data->vendor.vendor);
 
4137
}
 
4138
 
 
4139
static void
 
4140
NewVendorCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
4141
{
 
4142
    TreeNode *parent, *node = (TreeNode*)user_data;
 
4143
    XF86ConfVendorPtr vnd;
 
4144
    Arg args[1];
 
4145
    char *label;
 
4146
 
 
4147
    XtSetArg(args[0], XtNstring, &label);
 
4148
    XtGetValues(node->data->vendor.text, args, 1);
 
4149
    if (*label == '\0')
 
4150
        return;
 
4151
 
 
4152
    parent = node->parent;
 
4153
    DeleteNode(node);
 
4154
    vnd = (XF86ConfVendorPtr)XtCalloc(1, sizeof(XF86ConfVendorRec));
 
4155
    vnd->vnd_identifier = XtNewString(label);
 
4156
    XF86Config->conf_vendor_lst = xf86addVendor(XF86Config->conf_vendor_lst, vnd);
 
4157
 
 
4158
    CreateVendor(parent, vnd);
 
4159
    RelayoutTree();
 
4160
}
 
4161
 
 
4162
/* VendorSub */
 
4163
static void
 
4164
CreateVendorSub(TreeNode *parent, XF86ConfVendSubPtr vendor)
 
4165
{
 
4166
    TreeNode *prev, *node;
 
4167
    TreeData *data;
 
4168
 
 
4169
    if ((prev = parent->child) != NULL)
 
4170
        while (prev->next)
 
4171
            prev = prev->next;
 
4172
 
 
4173
    while (vendor) {
 
4174
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
4175
        data->vendsub.vendsub = vendor;
 
4176
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
4177
        node->destroy = VendorSubDestroy;
 
4178
        node->update = VendorSubUpdate;
 
4179
        CreateVendorSubField(node, False);
 
4180
        if (parent->child == NULL)
 
4181
            parent->child = node;
 
4182
        else
 
4183
            prev->next = node;
 
4184
        prev = node;
 
4185
        vendor = (XF86ConfVendSubPtr)(vendor->list.next);
 
4186
    }
 
4187
 
 
4188
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
4189
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
4190
    CreateVendorSubField(node, True);
 
4191
    if (parent->child == NULL)
 
4192
        parent->child = node;
 
4193
    else
 
4194
        prev->next = node;
 
4195
}
 
4196
 
 
4197
static void
 
4198
CreateVendorSubField(TreeNode *node, Bool addnew)
 
4199
{
 
4200
    Widget box, command;
 
4201
 
 
4202
    box = XtVaCreateWidget("vendorSub", formWidgetClass, tree,
 
4203
                           XtNtreeParent, node->treeParent, NULL);
 
4204
    node->node = box;
 
4205
 
 
4206
    if (!addnew) {
 
4207
        XF86OptionPtr *options;
 
4208
        XF86ConfVendSubPtr vendor = node->data->vendsub.vendsub;
 
4209
 
 
4210
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
4211
                                        NULL, 0);
 
4212
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
4213
        options = &(vendor->vs_option_lst);
 
4214
        command = XtCreateManagedWidget("options", commandWidgetClass, box,
 
4215
                                        NULL, 0);
 
4216
        XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
 
4217
        XtVaCreateManagedWidget("label", labelWidgetClass, box,
 
4218
                                XtNlabel, vendor->vs_identifier, NULL);
 
4219
 
 
4220
        XtCreateManagedWidget("nameL", labelWidgetClass, box, NULL, 0);
 
4221
        node->data->vendsub.text =
 
4222
            XtVaCreateManagedWidget("name", asciiTextWidgetClass, box,
 
4223
                                    XtNeditType, XawtextEdit, XtNstring,
 
4224
                                    vendor->vs_name ? vendor->vs_name : "",
 
4225
                                    NULL);
 
4226
    }
 
4227
    else {
 
4228
        command = XtCreateManagedWidget("new", commandWidgetClass, box,
 
4229
                                        NULL, 0);
 
4230
        XtAddCallback(command, XtNcallback, NewVendorSubCallback, (XtPointer)node);
 
4231
        node->data->vendsub.text =
 
4232
            XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
 
4233
                                    XtNeditType, XawtextEdit, NULL);
 
4234
    }
 
4235
    if (XtIsRealized(node->treeParent))
 
4236
        XtRealizeWidget(box);
 
4237
    XtManageChild(box);
 
4238
}
 
4239
 
 
4240
static void
 
4241
VendorSubDestroy(TreeNode *node)
 
4242
{
 
4243
    if (node->data->vendsub.vendsub)
 
4244
        xf86removeVendorSub(node->parent->parent->data->vendor.vendor,
 
4245
                            node->data->vendsub.vendsub);
 
4246
}
 
4247
 
 
4248
static void
 
4249
VendorSubUpdate(TreeNode *node)
 
4250
{
 
4251
    char *str;
 
4252
 
 
4253
    XtVaGetValues(node->data->vendsub.text, XtNstring, &str, NULL);
 
4254
    XtFree(node->data->vendsub.vendsub->vs_name);
 
4255
    if (*str)
 
4256
        node->data->vendsub.vendsub->vs_name = XtNewString(str);
 
4257
    else
 
4258
        node->data->vendsub.vendsub->vs_name = NULL;
 
4259
}
 
4260
 
 
4261
static void
 
4262
NewVendorSubCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
4263
{
 
4264
    TreeNode *parent, *node = (TreeNode*)user_data;
 
4265
    XF86ConfVendSubPtr vnd;
 
4266
    Arg args[1];
 
4267
    char *label;
 
4268
 
 
4269
    XtSetArg(args[0], XtNstring, &label);
 
4270
    XtGetValues(node->data->vendsub.text, args, 1);
 
4271
    if (*label == '\0')
 
4272
        return;
 
4273
 
 
4274
    parent = node->parent;
 
4275
    DeleteNode(node);
 
4276
    vnd = (XF86ConfVendSubPtr)XtCalloc(1, sizeof(XF86ConfVendSubRec));
 
4277
    vnd->vs_identifier = XtNewString(label);
 
4278
    parent->parent->data->vendor.vendor->vnd_sub_lst =
 
4279
        xf86addVendorSub(parent->parent->data->vendor.vendor->vnd_sub_lst, vnd);
 
4280
 
 
4281
    CreateVendorSub(parent, vnd);
 
4282
    RelayoutTree();
 
4283
}
 
4284
 
 
4285
/* DRI */
 
4286
static void
 
4287
CreateDRI(TreeNode *parent, XF86ConfDRIPtr dri)
 
4288
{
 
4289
    TreeNode *node;
 
4290
    TreeData *data;
 
4291
 
 
4292
    data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
4293
    data->dri.dri = dri;
 
4294
    node = NewNode(parent, NULL, NULL, parent->node, data);
 
4295
    parent->child = node;
 
4296
    node->update = DRIUpdate;
 
4297
    CreateDRIField(node);
 
4298
}
 
4299
 
 
4300
static void
 
4301
CreateDRIField(TreeNode *node)
 
4302
{
 
4303
    Widget box, toggle;
 
4304
    XF86ConfDRIPtr dri = node->data->dri.dri;
 
4305
    TreeNode *buffers;
 
4306
    char buf[32];
 
4307
 
 
4308
    box = XtVaCreateWidget("dri", formWidgetClass, tree,
 
4309
                           XtNtreeParent, node->treeParent, NULL);
 
4310
    node->node = box;
 
4311
    XtCreateManagedWidget("nameL", labelWidgetClass, box, NULL, 0);
 
4312
    node->data->dri.name =
 
4313
        XtVaCreateManagedWidget("name", asciiTextWidgetClass, box,
 
4314
                                XtNeditType, XawtextEdit, XtNstring,
 
4315
                                dri->dri_group_name ? dri->dri_group_name : "",
 
4316
                                NULL);
 
4317
 
 
4318
    XtCreateManagedWidget("groupL", labelWidgetClass, box, NULL, 0);
 
4319
    if (dri->dri_group >= 0)
 
4320
        XmuSnprintf(buf, sizeof(buf), "%d", dri->dri_group);
 
4321
    else
 
4322
        *buf = '\0';
 
4323
    node->data->dri.group =
 
4324
        XtVaCreateManagedWidget("group", asciiTextWidgetClass, box,
 
4325
                                XtNeditType, XawtextEdit, XtNstring, buf,
 
4326
                                NULL);
 
4327
 
 
4328
    XtCreateManagedWidget("modeL", labelWidgetClass, box, NULL, 0);
 
4329
    if (dri->dri_mode > 0)
 
4330
        XmuSnprintf(buf, sizeof(buf), "0%o", dri->dri_mode);
 
4331
    else
 
4332
        *buf = '\0';
 
4333
    node->data->dri.mode =
 
4334
        XtVaCreateManagedWidget("mode", asciiTextWidgetClass, box,
 
4335
                                XtNeditType, XawtextEdit, XtNstring, buf,
 
4336
                                NULL);
 
4337
 
 
4338
    toggle = XtVaCreateManagedWidget("Buffers", toggleWidgetClass, tree,
 
4339
                                     XtNstate, True, XtNtreeParent, box,
 
4340
                                     NULL);
 
4341
    buffers = NewNode(node, toggle, toggle, box, NULL);
 
4342
    node->child = buffers;
 
4343
    CreateBuffers(buffers, dri->dri_buffers_lst);
 
4344
 
 
4345
    if (XtIsRealized(node->treeParent))
 
4346
        XtRealizeWidget(box);
 
4347
    XtManageChild(box);
 
4348
}
 
4349
 
 
4350
static void
 
4351
DRIUpdate(TreeNode *node)
 
4352
{
 
4353
    char *str;
 
4354
 
 
4355
    /* name */
 
4356
    XtVaGetValues(node->data->dri.name, XtNstring, &str, NULL);
 
4357
    XtFree(node->data->dri.dri->dri_group_name);
 
4358
    if (*str)
 
4359
        node->data->dri.dri->dri_group_name = XtNewString(str);
 
4360
    else
 
4361
        node->data->dri.dri->dri_group_name = NULL;
 
4362
 
 
4363
    /* group */
 
4364
    XtVaGetValues(node->data->dri.group, XtNstring, &str, NULL);
 
4365
    if (*str)
 
4366
        node->data->dri.dri->dri_group = strtoul(str, NULL, 0);
 
4367
    else
 
4368
        node->data->dri.dri->dri_group = -1;
 
4369
 
 
4370
    /* mode */
 
4371
    XtVaGetValues(node->data->dri.mode, XtNstring, &str, NULL);
 
4372
    node->data->dri.dri->dri_mode = strtoul(str, NULL, 0);
 
4373
}
 
4374
 
 
4375
/* Buffers */
 
4376
static void
 
4377
CreateBuffers(TreeNode *parent, XF86ConfBuffersPtr buf)
 
4378
{
 
4379
    TreeNode *node, *prev;
 
4380
    TreeData *data;
 
4381
 
 
4382
    if ((prev = parent->child) != NULL)
 
4383
        while (prev->next)
 
4384
            prev = prev->next;
 
4385
 
 
4386
    while (buf) {
 
4387
        data = (TreeData*)XtCalloc(1, sizeof(TreeData));
 
4388
        data->buffers.buffers = buf;
 
4389
        node = NewNode(parent, NULL, NULL, parent->node, data);
 
4390
        node->destroy = BuffersDestroy;
 
4391
        node->update = BuffersUpdate;
 
4392
        CreateBuffersField(node, False);
 
4393
        if (parent->child == NULL)
 
4394
            parent->child = node;
 
4395
        else
 
4396
            prev->next = node;
 
4397
        prev = node;
 
4398
 
 
4399
        buf = (XF86ConfBuffersPtr)(buf->list.next);
 
4400
    }
 
4401
    node = NewNode(parent, NULL, NULL, parent->node, NULL);
 
4402
    CreateBuffersField(node, True);
 
4403
    if (parent->child == NULL)
 
4404
        parent->child = node;
 
4405
    else
 
4406
        prev->next = node;
 
4407
}
 
4408
 
 
4409
static void
 
4410
CreateBuffersField(TreeNode *node, Bool addnew)
 
4411
{
 
4412
    Widget box, command;
 
4413
 
 
4414
    box = XtVaCreateWidget("buffers", formWidgetClass, tree,
 
4415
                           XtNtreeParent, node->treeParent, NULL);
 
4416
    node->node = box;
 
4417
 
 
4418
    if (!addnew) {
 
4419
        char str[32];
 
4420
        XF86ConfBuffersPtr buf = node->data->buffers.buffers;
 
4421
 
 
4422
        command = XtCreateManagedWidget("remove", commandWidgetClass, box,
 
4423
                                        NULL, 0);
 
4424
        XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
 
4425
 
 
4426
        XtCreateManagedWidget("countL", labelWidgetClass, box, NULL, 0);
 
4427
        XmuSnprintf(str, sizeof(str), "%d", buf->buf_count);
 
4428
        node->data->buffers.count =
 
4429
            XtVaCreateManagedWidget("count", asciiTextWidgetClass, box,
 
4430
                                    XtNeditType, XawtextEdit, XtNstring, str,
 
4431
                                    NULL);
 
4432
 
 
4433
        XtCreateManagedWidget("sizeL", labelWidgetClass, box, NULL, 0);
 
4434
        XmuSnprintf(str, sizeof(str), "%d", buf->buf_size);
 
4435
        node->data->buffers.size =
 
4436
            XtVaCreateManagedWidget("size", asciiTextWidgetClass, box,
 
4437
                                    XtNeditType, XawtextEdit, XtNstring, str,
 
4438
                                    NULL);
 
4439
 
 
4440
        XtCreateManagedWidget("flagsL", labelWidgetClass, box, NULL, 0);
 
4441
        node->data->buffers.flags =
 
4442
            XtVaCreateManagedWidget("flags", asciiTextWidgetClass, box,
 
4443
                                    XtNeditType, XawtextEdit, XtNstring,
 
4444
                                    buf->buf_flags ? buf->buf_flags : "",
 
4445
                                    NULL);
 
4446
    }
 
4447
    else {
 
4448
        command = XtCreateManagedWidget("new", commandWidgetClass, box,
 
4449
                                        NULL, 0);
 
4450
        XtAddCallback(command, XtNcallback, NewBuffersCallback, (XtPointer)node);
 
4451
    }
 
4452
    if (XtIsRealized(node->treeParent))
 
4453
        XtRealizeWidget(box);
 
4454
    XtManageChild(box);
 
4455
}
 
4456
 
 
4457
/*ARGUSED*/
 
4458
static void
 
4459
BuffersDestroy(TreeNode *node)
 
4460
{
 
4461
    if (node->data->buffers.buffers)
 
4462
        xf86removeBuffers(XF86Config->conf_dri, node->data->buffers.buffers);
 
4463
}
 
4464
 
 
4465
/*ARGSUSED*/
 
4466
static void
 
4467
NewBuffersCallback(Widget unused, XtPointer user_data, XtPointer call_data)
 
4468
{
 
4469
    TreeNode *parent, *node = (TreeNode*)user_data;
 
4470
    XF86ConfBuffersPtr buf;
 
4471
 
 
4472
    parent = node->parent;
 
4473
    DeleteNode(node);
 
4474
    buf = (XF86ConfBuffersPtr)XtCalloc(1, sizeof(XF86ConfBuffersRec));
 
4475
    XF86Config->conf_dri->dri_buffers_lst =
 
4476
        xf86addBuffers(XF86Config->conf_dri->dri_buffers_lst, buf);
 
4477
 
 
4478
    CreateBuffers(parent, buf);
 
4479
    RelayoutTree();
 
4480
}
 
4481
 
 
4482
static void
 
4483
BuffersUpdate(TreeNode *node)
 
4484
{
 
4485
    char *str;
 
4486
 
 
4487
    /* count */
 
4488
    XtVaGetValues(node->data->buffers.count, XtNstring, &str, NULL);
 
4489
    node->data->buffers.buffers->buf_count = strtoul(str, NULL, 0);
 
4490
 
 
4491
    /* size */
 
4492
    XtVaGetValues(node->data->buffers.size, XtNstring, &str, NULL);
 
4493
    node->data->buffers.buffers->buf_size = strtoul(str, NULL, 0);
 
4494
 
 
4495
    /* flags */
 
4496
    XtVaGetValues(node->data->buffers.flags, XtNstring, &str, NULL);
 
4497
    if (*str)
 
4498
        node->data->buffers.buffers->buf_flags = XtNewString(str);
 
4499
    else
 
4500
        node->data->buffers.buffers->buf_flags = NULL;
 
4501
}
 
4502
 
 
4503
static TreeNode *
 
4504
NewNode(TreeNode *parent, Widget node, Widget toggle, Widget treeParent,
 
4505
        TreeData *data)
 
4506
{
 
4507
    TreeNode *tree = (TreeNode*)XtCalloc(1, sizeof(TreeNode));
 
4508
 
 
4509
    tree->parent = parent;
 
4510
    tree->node = node;
 
4511
    if ((tree->toggle = toggle) != NULL)
 
4512
        XtAddCallback(toggle, XtNcallback, ToggleCallback, (XtPointer)tree);
 
4513
    tree->treeParent = treeParent;
 
4514
    tree->data = data;
 
4515
 
 
4516
    return (tree);
 
4517
}
 
4518
 
 
4519
static void
 
4520
DeleteNode(TreeNode *node)
 
4521
{
 
4522
    TreeNode *ptr = node->child;
 
4523
 
 
4524
    while (ptr != NULL) {
 
4525
        TreeNode *next = ptr->next;
 
4526
 
 
4527
        DeleteNode(ptr);
 
4528
        ptr = next;
 
4529
    }
 
4530
 
 
4531
    if (node->parent && node->parent->child == node)
 
4532
        node->parent->child = node->next;
 
4533
    else if (node->parent) {
 
4534
        for (ptr = node->parent->child; ptr && ptr->next != node;
 
4535
             ptr = ptr->next)
 
4536
            ;
 
4537
        if (ptr)
 
4538
            ptr->next = node->next;
 
4539
    }
 
4540
 
 
4541
    if (node->destroy)
 
4542
        (node->destroy)(node);
 
4543
    if (node->data)
 
4544
        XtFree((XtPointer)node->data);
 
4545
 
 
4546
    /* sets treeParent to NULL so that RelayoutTree works correctly,
 
4547
     * as the tree will properly calculate it's new size.
 
4548
     */
 
4549
    XtVaSetValues(node->node, XtNtreeParent, NULL, NULL);
 
4550
 
 
4551
    XtDestroyWidget(node->node);
 
4552
    XtFree((XtPointer)node);
 
4553
}
 
4554
 
 
4555
/*ARGUSED*/
 
4556
static void
 
4557
DestroyCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
4558
{
 
4559
    TreeNode *node = (TreeNode*)user_data;
 
4560
 
 
4561
    DeleteNode(node);
 
4562
    RelayoutTree();
 
4563
}
 
4564
 
 
4565
static void
 
4566
ToggleNodeRecursive(TreeNode *node)
 
4567
{
 
4568
    while (node) {
 
4569
        if (!XtIsRealized(node->node))
 
4570
            XtRealizeWidget(node->node);
 
4571
        XtVaSetValues(node->node, XtNtreeParent, node->treeParent, NULL);
 
4572
        XtManageChild(node->node);
 
4573
 
 
4574
        if (node->child && !node->toggle)
 
4575
            ToggleNodeRecursive(node->child);
 
4576
 
 
4577
        node = node->next;
 
4578
    }
 
4579
}
 
4580
 
 
4581
static void
 
4582
ToggleNode(TreeNode *node, Bool toggle)
 
4583
{
 
4584
    while (node) {
 
4585
        if (toggle) {
 
4586
            if (!XtIsRealized(node->node))
 
4587
                XtRealizeWidget(node->node);
 
4588
            XtVaSetValues(node->node, XtNtreeParent, node->treeParent, NULL);
 
4589
            XtManageChild(node->node);
 
4590
 
 
4591
            if (node->child && !node->toggle)
 
4592
                ToggleNodeRecursive(node->child);
 
4593
        }
 
4594
        else {
 
4595
            if (node->child)
 
4596
                ToggleNode(node->child, False);
 
4597
            XtVaSetValues(node->node, XtNtreeParent, NULL, NULL);
 
4598
            XtUnmanageChild(node->node);
 
4599
            if (node->toggle)
 
4600
                XtVaSetValues(node->toggle, XtNstate, False, NULL);
 
4601
        }
 
4602
        node = node->next;
 
4603
    }
 
4604
}
 
4605
 
 
4606
/*
 
4607
 * XXX This callback can show side effects in the way it is called. If
 
4608
 * the structure holding the XF86OptionPtr is reallocated, a bogus pointer
 
4609
 * will be passed to this callback.
 
4610
 */
 
4611
static void
 
4612
OptionsCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
4613
{
 
4614
    XF86OptionPtr *options = (XF86OptionPtr*)user_data;
 
4615
 
 
4616
#ifdef USE_MODULES
 
4617
    OptionsPopup(options, NULL, NULL);
 
4618
#else
 
4619
    OptionsPopup(options);
 
4620
#endif
 
4621
}
 
4622
 
 
4623
static void
 
4624
RelayoutTree(void)
 
4625
{
 
4626
    Arg args[4];
 
4627
    Dimension sliderWidth, sliderHeight, canvasWidth, canvasHeight;
 
4628
 
 
4629
    XtSetArg(args[0], XtNwidth, &sliderWidth);
 
4630
    XtSetArg(args[1], XtNheight, &sliderHeight);
 
4631
    XtGetValues(shell, args, 2);
 
4632
 
 
4633
    XtSetArg(args[2], XtNwidth, &canvasWidth);
 
4634
    XtSetArg(args[3], XtNheight, &canvasHeight);
 
4635
    XtGetValues(tree, args + 2, 2);
 
4636
 
 
4637
    XtSetArg(args[0], XtNsliderWidth, sliderWidth);
 
4638
    XtSetArg(args[1], XtNsliderHeight, sliderHeight);
 
4639
    XtSetArg(args[2], XtNcanvasWidth, canvasWidth);
 
4640
    XtSetArg(args[3], XtNcanvasHeight, canvasHeight);
 
4641
    XtSetValues(panner, args, 4);
 
4642
}
 
4643
 
 
4644
static void
 
4645
ToggleCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
4646
{
 
4647
    TreeNode *nodeParent = (TreeNode*)user_data;
 
4648
 
 
4649
    if (nodeParent->child) {
 
4650
        if (XtIsRealized(tree))
 
4651
            XtUnmapWidget(tree);
 
4652
        ToggleNode(nodeParent->child, (Bool)(long)call_data);
 
4653
        RelayoutTree();
 
4654
        if (XtIsRealized(tree))
 
4655
            XtMapWidget(tree);
 
4656
    }
 
4657
}
 
4658
 
 
4659
/*ARGSUSED*/
 
4660
static void
 
4661
PannerCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
4662
{
 
4663
    Arg args[2];
 
4664
    XawPannerReport *rep = (XawPannerReport *)call_data;
 
4665
 
 
4666
    XtSetArg (args[0], XtNx, -rep->slider_x);
 
4667
    XtSetArg (args[1], XtNy, -rep->slider_y);
 
4668
    XtSetValues(tree, args, 2);
 
4669
}
 
4670
 
 
4671
/*ARGSUSED*/
 
4672
static void
 
4673
PortholeCallback(Widget w, XtPointer user_data, XtPointer call_data)
 
4674
{
 
4675
    XawPannerReport *rep = (XawPannerReport*)call_data;
 
4676
    Arg args[6];
 
4677
    Cardinal n = 2;
 
4678
 
 
4679
    XtSetArg (args[0], XtNsliderX, rep->slider_x);
 
4680
    XtSetArg (args[1], XtNsliderY, rep->slider_y);
 
4681
    if (rep->changed != (XawPRSliderX | XawPRSliderY)) {
 
4682
        XtSetArg (args[2], XtNsliderWidth, rep->slider_width);
 
4683
        XtSetArg (args[3], XtNsliderHeight, rep->slider_height);
 
4684
        XtSetArg (args[4], XtNcanvasWidth, rep->canvas_width);
 
4685
        XtSetArg (args[5], XtNcanvasHeight, rep->canvas_height);
 
4686
        n = 6;
 
4687
    }
 
4688
    XtSetValues(panner, args, n);
 
4689
}
 
4690
 
 
4691
static void
 
4692
DestroyTree(TreeNode *node)
 
4693
{
 
4694
    while (node) {
 
4695
        TreeNode *next = node->next;
 
4696
        if (node->child)
 
4697
            DestroyTree(node->child);
 
4698
 
 
4699
        if (node->data)
 
4700
            XtFree((XtPointer)node->data);
 
4701
        XtFree((XtPointer)node);
 
4702
 
 
4703
        node = next;
 
4704
    }
 
4705
}
 
4706
 
 
4707
static void
 
4708
UpdateConfig(TreeNode *node)
 
4709
{
 
4710
    while (node) {
 
4711
        if (node->child)
 
4712
            UpdateConfig(node->child);
 
4713
        if (node->update)
 
4714
            (node->update)(node);
 
4715
        node = node->next;
 
4716
    }
 
4717
}
 
4718
 
 
4719
static Bool
 
4720
ExpertInitialize(void)
 
4721
{
 
4722
    Widget paned, vpane, close, config, files, modules, flags, video, modes,
 
4723
           monitor, device, screen, input, layout, vendor, dri;
 
4724
    Arg args[4];
 
4725
    Dimension width, height, canvasWidth, canvasHeight;
 
4726
    TreeNode *node;
 
4727
 
 
4728
    if (expert != NULL)
 
4729
        return (False);
 
4730
 
 
4731
    shell = XtCreatePopupShell("Expert", transientShellWidgetClass,
 
4732
                               toplevel, NULL, 0);
 
4733
    paned = XtVaCreateManagedWidget("paned", panedWidgetClass, shell,
 
4734
                                    XtNorientation, XtorientHorizontal, NULL);
 
4735
    vpane = XtCreateManagedWidget("vpane", panedWidgetClass, paned, NULL, 0);
 
4736
    panner = XtCreateManagedWidget ("panner", pannerWidgetClass, vpane, NULL, 0);
 
4737
    close = XtCreateManagedWidget("close", commandWidgetClass, vpane, NULL, 0);
 
4738
    XtAddCallback(close, XtNcallback, PopdownCallback, NULL);
 
4739
 
 
4740
    expert = XtCreateManagedWidget("expert", portholeWidgetClass, paned, NULL, 0);
 
4741
    XtAddCallback(expert, XtNreportCallback, PortholeCallback, NULL);
 
4742
    XtAddCallback(panner, XtNreportCallback, PannerCallback, NULL);
 
4743
    tree = XtCreateManagedWidget("tree", treeWidgetClass, expert, NULL, 0);
 
4744
 
 
4745
    config = XtVaCreateManagedWidget(__XCONFIGFILE__, toggleWidgetClass, tree,
 
4746
                                     XtNstate, True, NULL);
 
4747
    mainNode = NewNode(NULL, config, config, NULL, NULL);
 
4748
 
 
4749
    files = XtVaCreateManagedWidget("Files", toggleWidgetClass, tree,
 
4750
                                    XtNtreeParent, config, NULL);
 
4751
    node = NewNode(mainNode, files, files, config, NULL);
 
4752
    mainNode->child = node;
 
4753
    CreateFiles(node);
 
4754
 
 
4755
    modules = XtVaCreateManagedWidget("Module", toggleWidgetClass, tree,
 
4756
                                      XtNtreeParent, config, NULL);
 
4757
    node->next = NewNode(mainNode, modules, modules, config, NULL);
 
4758
    node = node->next;
 
4759
    CreateModule(node, XF86Config->conf_modules ?
 
4760
                 XF86Config->conf_modules->mod_load_lst : NULL);
 
4761
 
 
4762
    flags = XtVaCreateManagedWidget("ServerFlags", commandWidgetClass, tree,
 
4763
                                    XtNtreeParent, config, NULL);
 
4764
    node->next = NewNode(mainNode, flags, NULL, config, NULL);
 
4765
    node = node->next;
 
4766
    if (XF86Config->conf_flags == NULL)
 
4767
        XF86Config->conf_flags = (XF86ConfFlagsPtr)
 
4768
            XtCalloc(1, sizeof(XF86ConfFlagsRec));
 
4769
    XtAddCallback(flags, XtNcallback, OptionsCallback,
 
4770
                  (XtPointer)&(XF86Config->conf_flags->flg_option_lst));
 
4771
 
 
4772
    video = XtVaCreateManagedWidget("VideoAdaptor", toggleWidgetClass, tree,
 
4773
                                     XtNtreeParent, config, NULL);
 
4774
    node->next = NewNode(mainNode, video, video, config, NULL);
 
4775
    node = node->next;
 
4776
    CreateVideoAdaptor(node, XF86Config->conf_videoadaptor_lst);
 
4777
 
 
4778
    modes = XtVaCreateManagedWidget("Mode", toggleWidgetClass, tree,
 
4779
                                    XtNtreeParent, config, NULL);
 
4780
    node->next = NewNode(mainNode, modes, modes, config, NULL);
 
4781
    node = node->next;
 
4782
    CreateModes(node, XF86Config->conf_modes_lst);
 
4783
 
 
4784
    monitor = XtVaCreateManagedWidget("Monitor", toggleWidgetClass, tree,
 
4785
                                      XtNtreeParent, config, NULL);
 
4786
    node->next = NewNode(mainNode, monitor, monitor, config, NULL);
 
4787
    node = node->next;
 
4788
    CreateMonitor(monitorTree = node, XF86Config->conf_monitor_lst);
 
4789
 
 
4790
    device = XtVaCreateManagedWidget("Device", toggleWidgetClass, tree,
 
4791
                                     XtNtreeParent, config, NULL);
 
4792
    node->next = NewNode(mainNode, device, device, config, NULL);
 
4793
    node = node->next;
 
4794
    CreateDevice(node, XF86Config->conf_device_lst);
 
4795
 
 
4796
    screen = XtVaCreateManagedWidget("Screen", toggleWidgetClass, tree,
 
4797
                                     XtNtreeParent, config, NULL);
 
4798
    node->next = NewNode(mainNode, screen, screen, config, NULL);
 
4799
    node = node->next;
 
4800
    CreateScreen(screenTree = node, XF86Config->conf_screen_lst);
 
4801
 
 
4802
    input = XtVaCreateManagedWidget("Input", toggleWidgetClass, tree,
 
4803
                                    XtNtreeParent, config, NULL);
 
4804
    node->next = NewNode(mainNode, input, input, config, NULL);
 
4805
    node = node->next;
 
4806
    CreateInput(node, XF86Config->conf_input_lst);
 
4807
 
 
4808
    layout = XtVaCreateManagedWidget("Layout", toggleWidgetClass, tree,
 
4809
                                     XtNtreeParent, config, NULL);
 
4810
    node->next = NewNode(mainNode, layout, layout, config, NULL);
 
4811
    node = node->next;
 
4812
    CreateLayout(layoutTree = node, XF86Config->conf_layout_lst);
 
4813
 
 
4814
    vendor = XtVaCreateManagedWidget("Vendor", toggleWidgetClass, tree,
 
4815
                                     XtNtreeParent, config, NULL);
 
4816
    node->next = NewNode(mainNode, vendor, vendor, config, NULL);
 
4817
    node = node->next;
 
4818
    CreateVendor(node, XF86Config->conf_vendor_lst);
 
4819
 
 
4820
    dri = XtVaCreateManagedWidget("DRI", toggleWidgetClass, tree,
 
4821
                                  XtNtreeParent, config, NULL);
 
4822
    node->next = NewNode(mainNode, dri, dri, config, NULL);
 
4823
    node = node->next;
 
4824
    if (XF86Config->conf_dri == NULL)
 
4825
        XF86Config->conf_dri = (XF86ConfDRIPtr)
 
4826
            XtCalloc(1, sizeof(XF86ConfDRIRec));
 
4827
    CreateDRI(node, XF86Config->conf_dri);
 
4828
 
 
4829
    XtRealizeWidget(shell);
 
4830
 
 
4831
    XtSetArg(args[0], XtNwidth, &width);
 
4832
    XtSetArg(args[1], XtNheight, &height);
 
4833
    XtGetValues(shell, args, 2);
 
4834
    XtSetArg(args[0], XtNwidth, width);
 
4835
    XtSetArg(args[1], XtNheight, height);
 
4836
    XtSetValues(expert, args, 2);
 
4837
 
 
4838
    XtSetArg(args[0], XtNsliderWidth, width);
 
4839
    XtSetArg(args[1], XtNsliderHeight, height);
 
4840
    XtSetArg(args[2], XtNwidth, &canvasWidth);
 
4841
    XtSetArg(args[3], XtNheight, &canvasHeight);
 
4842
    XtGetValues(tree, args + 2, 2);
 
4843
    XtSetArg(args[2], XtNcanvasWidth, canvasWidth);
 
4844
    XtSetArg(args[3], XtNcanvasHeight, canvasHeight);
 
4845
    XtSetValues(panner, args, 4);
 
4846
 
 
4847
    /* needs to do the apparently NOP code bellow to correctly layout the
 
4848
     * tree widget */
 
4849
 
 
4850
    /* close all open entries */
 
4851
    ToggleCallback(config, mainNode, (XtPointer)0);
 
4852
    /* open first level */
 
4853
    ToggleCallback(config, mainNode, (XtPointer)1);
 
4854
 
 
4855
    XSetWMProtocols(DPY, XtWindow(shell), &wm_delete_window, 1);
 
4856
 
 
4857
    return (True);
 
4858
}