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