summaryrefslogtreecommitdiff
path: root/hw/xfree86/utils/xorgcfg/expert.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xfree86/utils/xorgcfg/expert.c')
-rw-r--r--hw/xfree86/utils/xorgcfg/expert.c4860
1 files changed, 4860 insertions, 0 deletions
diff --git a/hw/xfree86/utils/xorgcfg/expert.c b/hw/xfree86/utils/xorgcfg/expert.c
new file mode 100644
index 000000000..b9890b32b
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/expert.c
@@ -0,0 +1,4860 @@
+/*
+ * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * CONECTIVA LINUX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Conectiva Linux shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization from
+ * Conectiva Linux.
+ *
+ * Author: Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
+ *
+ * $XFree86: xc/programs/Xserver/hw/xfree86/xf86cfg/expert.c,v 1.14 2003/02/07 05:46:53 paulo Exp $
+ */
+
+#include "config.h"
+#include "xf86config.h"
+#include "options.h"
+#include "screen.h"
+#include "vidmode.h"
+#include "monitor-cfg.h"
+#include <X11/Shell.h>
+#include <X11/CompositeP.h>
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/Box.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/MenuButton.h>
+#include <X11/Xaw/Paned.h>
+#include <X11/Xaw/Panner.h>
+#include <X11/Xaw/Porthole.h>
+#include <X11/Xaw/SimpleMenu.h>
+#include <X11/Xaw/SmeBSB.h>
+#include <X11/Xaw/Toggle.h>
+#include <X11/Xaw/Tree.h>
+#include <ctype.h>
+
+/*
+ * Types
+ */
+typedef struct _TreeNode TreeNode;
+typedef union _TreeData TreeData;
+typedef void (*NodeDeleteFunc)(TreeNode*);
+typedef void (*NodeUpdateFunc)(TreeNode*);
+
+union _TreeData {
+ struct {
+ Widget text;
+ } files;
+ struct {
+ Widget text;
+ XF86LoadPtr load;
+ } module;
+ struct {
+ Widget text;
+ XF86ConfModesPtr modes;
+ } modes;
+ struct {
+ Widget text, value;
+ XF86ConfModeLinePtr modeline;
+ } modeline;
+ struct {
+ Widget text, vendor, board, busid, driver;
+ XF86ConfVideoAdaptorPtr video;
+ } video;
+ struct {
+ Widget text;
+ XF86ConfVideoPortPtr port;
+ } port;
+ struct {
+ Widget text, vendor, model, width, height, hsync, vrefresh,
+ gammaRed, gammaGreen, gammaBlue;
+ XF86ConfMonitorPtr monitor;
+ } monitor;
+ struct {
+ Widget menu;
+ XF86ConfModesLinkPtr modeslink;
+ } modeslink;
+ struct {
+ Widget text, vendor, board, chipset, busid, card, driver, ramdac,
+ dacSpeed, videoRam, textClockFreq, biosBase, memBase, ioBase,
+ clockChip, devClock, chipId, chipRev, irq, screen;
+ XF86ConfDevicePtr device;
+ } device;
+ struct {
+ Widget text, defaultDepth, defaultBpp, defaultFbBpp,
+ monitor, device;
+ XF86ConfScreenPtr screen;
+ } screen;
+ struct {
+ Widget menu;
+ XF86ConfAdaptorLinkPtr adaptorlink;
+ } adaptorlink;
+ struct {
+ Widget viewport, c_virtual, depth, bpp, visual, weight, black, white;
+ XF86ConfDisplayPtr display;
+ } display;
+ struct {
+ Widget text;
+ XF86ModePtr mode;
+ } mode;
+ struct {
+ Widget text;
+ XF86ConfInputPtr input;
+ } input;
+ struct {
+ Widget text;
+ XF86ConfLayoutPtr layout;
+ } layout;
+ struct {
+ Widget menu, button, scrnum, adjx, adjy;
+ XF86ConfScreenPtr screen;
+ XF86ConfAdjacencyPtr adjacency;
+ } adjacency;
+ struct {
+ Widget menu;
+ XF86ConfInputrefPtr inputref;
+ } inputref;
+ struct {
+ Widget text;
+ XF86ConfVendorPtr vendor;
+ } vendor;
+ struct {
+ Widget text;
+ XF86ConfVendSubPtr vendsub;
+ } vendsub;
+ struct {
+ Widget name, group, mode;
+ XF86ConfDRIPtr dri;
+ } dri;
+ struct {
+ Widget count, size, flags;
+ XF86ConfBuffersPtr buffers;
+ } buffers;
+};
+
+struct _TreeNode {
+ Widget node, toggle, treeParent;
+ TreeNode *parent, *child, *next;
+ TreeData *data;
+ NodeDeleteFunc destroy;
+ NodeUpdateFunc update;
+};
+
+/*
+ * Prototypes
+ */
+static Bool ExpertInitialize(void);
+static TreeNode *NewNode(TreeNode*, Widget, Widget, Widget, TreeData*);
+static void DeleteNode(TreeNode*);
+static void DestroyCallback(Widget, XtPointer, XtPointer);
+static void PannerCallback(Widget, XtPointer, XtPointer);
+static void PortholeCallback(Widget, XtPointer, XtPointer);
+static void ToggleCallback(Widget, XtPointer, XtPointer);
+static void ToggleNode(TreeNode*, Bool);
+static void ToggleNodeRecursive(TreeNode*);
+static void OptionsCallback(Widget, XtPointer, XtPointer);
+static void RelayoutTree(void);
+static void PopdownCallback(Widget, XtPointer, XtPointer);
+static void UpdateConfig(TreeNode*);
+static void DestroyTree(TreeNode*);
+
+static void CreateFiles(TreeNode*);
+static void CreateFilesField(TreeNode*, char*, char*);
+static void UpdateFiles(TreeNode*);
+
+static void CreateFontPath(TreeNode*, char*);
+static Widget CreateFontPathField(TreeNode*, char*, Bool);
+static void FontPathChanged(TreeNode*);
+static void NewFontPathCallback(Widget, XtPointer, XtPointer);
+static void FontPathCallback(Widget, XtPointer, XtPointer);
+
+static void CreateModulePath(TreeNode*, char*);
+static Widget CreateModulePathField(TreeNode*, char*, Bool);
+static void ModulePathChanged(TreeNode*);
+static void NewModulePathCallback(Widget, XtPointer, XtPointer);
+
+static void CreateModule(TreeNode*, XF86LoadPtr);
+static void CreateModuleField(TreeNode*, Bool);
+static void ModuleDestroy(TreeNode*);
+static void NewModuleCallback(Widget, XtPointer, XtPointer);
+
+static void CreateModes(TreeNode*, XF86ConfModesPtr);
+static void CreateModesField(TreeNode*, Bool);
+static void ModesDestroy(TreeNode*);
+static void NewModesCallback(Widget, XtPointer, XtPointer);
+static void CreateModesModeLine(TreeNode*, XF86ConfModeLinePtr);
+static void ModesModeLineDestroy(TreeNode*);
+static void NewModesModeLineCallback(Widget, XtPointer, XtPointer);
+
+static void CreateModeLineField(TreeNode*, Bool, Bool);
+static XF86ConfModeLinePtr ParseModeLine(char*, char*);
+
+static void CreateVideoAdaptor(TreeNode*, XF86ConfVideoAdaptorPtr);
+static void CreateVideoAdaptorField(TreeNode*, Bool);
+static void VideoAdaptorDestroy(TreeNode*);
+static void NewVideoAdaptorCallback(Widget, XtPointer, XtPointer);
+static void VideoAdaptorUpdate(TreeNode*);
+static void CreateVideoPort(TreeNode*, XF86ConfVideoPortPtr);
+static void CreateVideoPortField(TreeNode*, Bool);
+static void VideoPortDestroy(TreeNode*);
+static void NewVideoPortCallback(Widget, XtPointer, XtPointer);
+
+static void CreateMonitor(TreeNode*, XF86ConfMonitorPtr);
+static void CreateMonitorField(TreeNode*, Bool);
+static void MonitorDestroy(TreeNode*);
+static void NewMonitorCallback(Widget, XtPointer, XtPointer);
+static void MonitorUpdate(TreeNode*);
+static void CreateMonitorModeLine(TreeNode*, XF86ConfModeLinePtr);
+static void MonitorModeLineDestroy(TreeNode*);
+static void NewMonitorModeLineCallback(Widget, XtPointer, XtPointer);
+static void CreateMonitorModes(TreeNode*, XF86ConfModesLinkPtr);
+static void CreateMonitorModesField(TreeNode*, Bool);
+static void MonitorModesLinkDestroy(TreeNode*);
+static void NewMonitorModesCallback(Widget, XtPointer, XtPointer);
+
+static void CreateDevice(TreeNode*, XF86ConfDevicePtr);
+static void CreateDeviceField(TreeNode*, Bool);
+static void NewDeviceCallback(Widget, XtPointer, XtPointer);
+static void DeviceDestroy(TreeNode*);
+static void DeviceUpdate(TreeNode*);
+
+static void CreateScreen(TreeNode*, XF86ConfScreenPtr);
+static void CreateScreenField(TreeNode*, Bool);
+static void NewScreenCallback(Widget, XtPointer, XtPointer);
+static void ScreenDestroy(TreeNode*);
+static void ScreenUpdate(TreeNode*);
+static void CreateScreenAdaptor(TreeNode*, XF86ConfAdaptorLinkPtr);
+static void CreateScreenAdaptorField(TreeNode*, Bool);
+static void NewScreenAdaptorCallback(Widget, XtPointer, XtPointer);
+static void ScreenAdaptorDestroy(TreeNode*);
+static void CreateScreenDisplay(TreeNode*, XF86ConfDisplayPtr);
+static void CreateScreenDisplayField(TreeNode*, Bool);
+static void NewScreenDisplayCallback(Widget, XtPointer, XtPointer);
+static void ScreenDisplayDestroy(TreeNode*);
+static void ScreenDisplayUpdate(TreeNode*);
+static void CreateDisplayMode(TreeNode*, XF86ModePtr);
+static void CreateDisplayModeField(TreeNode*, Bool);
+static void NewDisplayModeCallback(Widget, XtPointer, XtPointer);
+static void DisplayModeDestroy(TreeNode*);
+
+static void CreateInput(TreeNode*, XF86ConfInputPtr);
+static void CreateInputField(TreeNode*, Bool);
+static void InputDestroy(TreeNode*);
+static void NewInputCallback(Widget, XtPointer, XtPointer);
+static void InputUpdate(TreeNode*);
+
+static void CreateLayout(TreeNode*, XF86ConfLayoutPtr);
+static void CreateLayoutField(TreeNode*, Bool);
+static void LayoutDestroy(TreeNode*);
+static void NewLayoutCallback(Widget, XtPointer, XtPointer);
+static void CreateAdjacency(TreeNode*, XF86ConfAdjacencyPtr);
+static void CreateAdjacencyField(TreeNode*, Bool);
+static void AdjacencyDestroy(TreeNode*);
+static void NewAdjacencyCallback(Widget, XtPointer, XtPointer);
+static void AdjacencyMenuCallback(Widget, XtPointer, XtPointer);
+static void AdjacencyToggleCallback(Widget, XtPointer, XtPointer);
+static void CreateInputref(TreeNode*, XF86ConfInputrefPtr);
+static void CreateInputrefField(TreeNode*, Bool);
+static void InputrefDestroy(TreeNode*);
+static void NewInputrefCallback(Widget, XtPointer, XtPointer);
+
+static void CreateVendor(TreeNode*, XF86ConfVendorPtr);
+static void CreateVendorField(TreeNode*, Bool);
+static void VendorDestroy(TreeNode*);
+static void NewVendorCallback(Widget, XtPointer, XtPointer);
+static void CreateVendorSub(TreeNode*, XF86ConfVendSubPtr);
+static void CreateVendorSubField(TreeNode*, Bool);
+static void NewVendorSubCallback(Widget, XtPointer, XtPointer);
+static void VendorSubDestroy(TreeNode*);
+static void VendorSubUpdate(TreeNode*);
+
+static void CreateDRI(TreeNode*, XF86ConfDRIPtr);
+static void CreateDRIField(TreeNode*);
+static void DRIUpdate(TreeNode*);
+
+static void CreateBuffers(TreeNode*, XF86ConfBuffersPtr);
+static void CreateBuffersField(TreeNode*, Bool);
+static void BuffersDestroy(TreeNode*);
+static void NewBuffersCallback(Widget, XtPointer, XtPointer);
+static void BuffersUpdate(TreeNode*);
+
+extern void RemoveDeviceCallback(Widget, XtPointer, XtPointer);
+
+/* interface.c */
+extern void InitializeDevices(void);
+extern void SelectLayoutCallback(Widget, XtPointer, XtPointer);
+extern void UpdateMenuDeviceList(int);
+extern void SetConfigModeCallback(Widget, XtPointer, XtPointer);
+extern void DefaultLayoutCallback(Widget, XtPointer, XtPointer);
+extern void RemoveLayoutCallback(Widget, XtPointer, XtPointer);
+
+/*
+ * Initialization
+ */
+static Widget shell, expert, tree, panner;
+extern Widget work, optionsShell, config, layoutp, topMenu;
+extern xf86cfgDevice cpu_device;
+static TreeNode *mainNode, *monitorTree, *screenTree, *layoutTree;
+
+/*
+ * Implementation
+ */
+void
+ExpertConfigureStart(void)
+{
+ ExpertInitialize();
+
+ XtPopup(shell, XtGrabExclusive);
+ if (optionsShell == NULL)
+ CreateOptionsShell();
+ XtVaSetValues(optionsShell, XtNtransientFor, shell, NULL, 0);
+}
+
+void
+ExpertConfigureEnd(void)
+{
+ int i, save_config_mode = config_mode;
+ Widget sme, layopt, layoutsme = NULL;
+ XF86ConfLayoutPtr lay;
+
+ XtVaSetValues(optionsShell, XtNtransientFor, toplevel, NULL, 0);
+ XtPopdown(shell);
+
+ /* Need to do this to avoid all code elsewhere needing to update the
+ * "expert" widget tree
+ */
+ UpdateConfig(mainNode);
+ DestroyTree(mainNode);
+ XtDestroyWidget(shell);
+ expert = NULL;
+
+ if (save_config_mode != CONFIG_LAYOUT)
+ SetConfigModeCallback(topMenu, (XtPointer)CONFIG_LAYOUT, NULL);
+
+ /* Reset everything as the "expert" interface can do almost anything
+ * to the configuration.
+ */
+ for (i = 0; i < computer.num_screens; i++) {
+ XtDestroyWidget(computer.screens[i]->widget);
+ XtFree((XtPointer)computer.screens[i]);
+ }
+ XtFree((XtPointer)computer.screens);
+ computer.screens = NULL;
+ computer.num_screens = 0;
+
+ for (i = 0; i < computer.num_devices; i++) {
+ XtDestroyWidget(computer.devices[i]->widget);
+ XtFree((XtPointer)computer.devices[i]);
+ }
+ XtFree((XtPointer)computer.devices);
+ computer.devices = NULL;
+ computer.num_devices = 0;
+
+ for (i = 0; i < computer.num_layouts; i++) {
+ XtFree((XtPointer)computer.layouts[i]->position);
+ XtFree((XtPointer)computer.layouts[i]);
+ }
+ XtFree((XtPointer)computer.layouts);
+ computer.layouts = NULL;
+ computer.num_layouts = 0;
+
+ for (i = 0; i < computer.num_vidmodes; i++)
+ XtFree((XtPointer)computer.vidmodes[i]);
+ XtFree((XtPointer)computer.vidmodes);
+ computer.vidmodes = NULL;
+ computer.num_vidmodes = 0;
+
+ /* Reinitialize devices/screens */
+ InitializeDevices();
+ UpdateMenuDeviceList(MOUSE);
+ UpdateMenuDeviceList(KEYBOARD);
+ UpdateMenuDeviceList(CARD);
+ UpdateMenuDeviceList(MONITOR);
+
+ /* Update layout menu */
+ /* first entry is "New server layout" */
+ for (i = 1; i < ((CompositeWidget)layoutp)->composite.num_children; i++)
+ XtDestroyWidget(((CompositeWidget)layoutp)->composite.children[i]);
+ for (i = 0; i < layoutp->core.num_popups; i++)
+ XtDestroyWidget(layoutp->core.popup_list[i]);
+ lay = XF86Config->conf_layout_lst;
+ while (lay != NULL) {
+ sme = XtVaCreateManagedWidget("sme", smeBSBObjectClass,
+ layoutp,
+ XtNlabel, lay->lay_identifier,
+ XtNmenuName, lay->lay_identifier,
+ XtNleftBitmap, menuPixmap,
+ NULL, 0);
+ XtAddCallback(sme, XtNcallback, SelectLayoutCallback, (XtPointer)lay);
+ if (layoutsme == NULL)
+ layoutsme = sme;
+ layopt = XtCreatePopupShell(lay->lay_identifier, simpleMenuWidgetClass,
+ layoutp, NULL, 0);
+ sme = XtCreateManagedWidget("default", smeBSBObjectClass,
+ layopt, NULL, 0);
+ XtAddCallback(sme, XtNcallback, DefaultLayoutCallback, NULL);
+ sme = XtCreateManagedWidget("remove", smeBSBObjectClass,
+ layopt, NULL, 0);
+ XtAddCallback(sme, XtNcallback, RemoveLayoutCallback, NULL);
+ XtRealizeWidget(layopt);
+
+ lay = (XF86ConfLayoutPtr)(lay->list.next);
+ }
+ computer.layout = NULL;
+ SelectLayoutCallback(layoutsme,
+ XF86Config->conf_layout_lst, NULL);
+
+
+ if (XF86Config->conf_flags && XF86Config->conf_flags->flg_option_lst)
+ SetTip(&cpu_device);
+ for (i = 0; i < computer.num_devices; i++)
+ SetTip(computer.devices[i]);
+
+ /* Reinitialize vidmodes */
+ InitializeVidmodes();
+
+ if (save_config_mode != CONFIG_LAYOUT)
+ SetConfigModeCallback(topMenu, (XtPointer)(long)save_config_mode, NULL);
+}
+
+/*ARGSUSED*/
+void
+ExpertCloseAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+ ExpertConfigureEnd();
+}
+
+/*ARGSUSED*/
+void
+ExpertCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ ExpertConfigureStart();
+}
+
+/*ARGSUSED*/
+static void
+PopdownCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ ExpertConfigureEnd();
+}
+
+/* Files */
+static void
+CreateFiles(TreeNode *files)
+{
+ XF86ConfFilesPtr file = XF86Config->conf_files;
+ TreeNode *node, *fontpath, *modulepath;
+ Widget w;
+ char *value;
+
+ value = file->file_logfile ? file->file_logfile : "";
+ node = NewNode(files, NULL, NULL, files->node,
+ (TreeData*)XtCalloc(1, sizeof(TreeData)));
+ CreateFilesField(node, "LogFile", value);
+ files->child = node;
+ files->update = UpdateFiles;
+
+ if (XF86RGB_path)
+ value = XF86RGB_path;
+ else
+ value = file->file_rgbpath ? file->file_rgbpath : "";
+ node->next = NewNode(files, NULL, NULL, files->node,
+ (TreeData*)XtCalloc(1, sizeof(TreeData)));
+ node = node->next;
+ CreateFilesField(node, "RgbPath", value);
+
+ w = XtVaCreateManagedWidget("ModulePath", toggleWidgetClass, tree,
+ XtNtreeParent, files->node, NULL, 0);
+ node->next = modulepath = NewNode(files, w, w, files->node, NULL);
+ node = node->next;
+ CreateModulePath(modulepath, NULL);
+
+ w = XtVaCreateManagedWidget("FontPath", toggleWidgetClass, tree,
+ XtNtreeParent, files->node, NULL, 0);
+ node->next = fontpath = NewNode(files, w, w, files->node, NULL);
+ node = node->next;
+ CreateFontPath(fontpath, NULL);
+}
+
+static void
+CreateFilesField(TreeNode *node, char *name, char *value)
+{
+ Widget box, label, text;
+
+ box = XtVaCreateManagedWidget(name, boxWidgetClass, tree,
+ XtNtreeParent, node->node, NULL, 0);
+ node->node = box;
+ label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, name, NULL, 0);
+ text = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit, XtNstring, value,
+ NULL, 0);
+ node->data->files.text = text;
+}
+
+static void
+UpdateFiles(TreeNode *files)
+{
+ char *str;
+
+ /* LogFile */
+ files = files->child;
+ XtVaGetValues(files->data->files.text, XtNstring, &str, NULL, 0);
+ XtFree(XF86Config->conf_files->file_logfile);
+ if (*str)
+ XF86Config->conf_files->file_logfile = XtNewString(str);
+ else
+ XF86Config->conf_files->file_logfile = NULL;
+
+ /* LogFile */
+ files = files->next;
+ XtVaGetValues(files->data->files.text, XtNstring, &str, NULL, 0);
+ XtFree(XF86Config->conf_files->file_rgbpath);
+ if (*str)
+ XF86Config->conf_files->file_rgbpath = XtNewString(str);
+ else
+ XF86Config->conf_files->file_rgbpath = NULL;
+}
+
+/* FontPath */
+/* Don't need to set the update tree field, as it is already set
+ * as the destroy field */
+static void
+CreateFontPath(TreeNode *fontpath, char *path)
+{
+ TreeNode *prev = NULL, *node;
+ Widget w;
+
+ if (path == NULL) {
+ if (XF86Font_path) {
+ path = XtNewString(XF86Font_path);
+ if (XF86Config->conf_files && XF86Config->conf_files->file_fontpath) {
+ XtFree(XF86Config->conf_files->file_fontpath);
+ XF86Config->conf_files->file_fontpath = XtNewString(path);
+ }
+ }
+ else if (XF86Config->conf_files && XF86Config->conf_files->file_fontpath)
+ path = XtNewString(XF86Config->conf_files->file_fontpath);
+ }
+ else {
+ path = XtNewString(path);
+ if ((prev = fontpath->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+ }
+
+ if (path) {
+ char *s;
+
+ for (s = strtok(path, ","); s != NULL; s = strtok(NULL, ",")) {
+ node = NewNode(fontpath, NULL, NULL, fontpath->node, NULL);
+ node->destroy = FontPathChanged;
+ w = CreateFontPathField(node, s, False);
+ if (fontpath->child == NULL)
+ fontpath->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ }
+ XtFree(path);
+ }
+
+ node = NewNode(fontpath, NULL, NULL, fontpath->node, NULL);
+ w = CreateFontPathField(node, "", True);
+ if (fontpath->child == NULL)
+ fontpath->child = node;
+ else
+ prev->next = node;
+}
+
+static Widget
+CreateFontPathField(TreeNode *fontpath, char *value, Bool addnew)
+{
+ Widget box, command, text;
+ TreeData *data;
+
+ box = XtVaCreateWidget("fontpath", formWidgetClass, tree,
+ XtNtreeParent, fontpath->treeParent, NULL, 0);
+ fontpath->node = box;
+ if (!addnew) {
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback,
+ (XtPointer)fontpath);
+ command = XtCreateManagedWidget("up", commandWidgetClass, box, NULL, 0);
+ XtAddCallback(command, XtNcallback, FontPathCallback,
+ (XtPointer)fontpath);
+ command = XtCreateManagedWidget("down", commandWidgetClass, box, NULL, 0);
+ XtAddCallback(command, XtNcallback, FontPathCallback,
+ (XtPointer)fontpath);
+ text = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, value, NULL, 0);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box, NULL, 0);
+ XtAddCallback(command, XtNcallback, NewFontPathCallback,
+ (XtPointer)fontpath);
+ text = XtVaCreateManagedWidget("valueNew", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, value, NULL, 0);
+ }
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->files.text = text;
+ fontpath->data = data;
+
+ if (fontpath->treeParent && XtIsRealized(fontpath->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+
+ return (box);
+}
+
+static void
+FontPathChanged(TreeNode *node)
+{
+ TreeNode *parent = node->parent;
+ char *fontpath = NULL, *str;
+ Arg args[1];
+ int pos = 0, len;
+
+ /* last node is the "new" */
+ for (node = parent->child; node->next != NULL; node = node->next) {
+ if (pos)
+ fontpath[pos++] = ',';
+ XtSetArg(args[0], XtNstring, &str);
+ XtGetValues(node->data->files.text, args, 1);
+ len = strlen(str) + 2;
+ fontpath = XtRealloc(fontpath, pos + len);
+ strcpy(fontpath + pos, str);
+ pos += len - 2;
+ }
+
+ if (XF86Config->conf_files->file_fontpath)
+ XtFree(XF86Config->conf_files->file_fontpath);
+ XF86Config->conf_files->file_fontpath = fontpath;
+}
+
+static void
+NewFontPathCallback(Widget unused, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *fontpath, *node = (TreeNode*)user_data;
+ Arg args[1];
+ char *str;
+
+ XtSetArg(args[0], XtNstring, &str);
+ XtGetValues(node->data->files.text, args, 1);
+ if (*str == '\0')
+ return;
+
+ fontpath = node->parent;
+ DeleteNode(node);
+ CreateFontPath(fontpath, str);
+
+ FontPathChanged(fontpath->child);
+ RelayoutTree();
+}
+
+/*ARGSUSED*/
+static void
+FontPathCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node, *fontpath = (TreeNode*)user_data;
+ char *t1, *t2;
+ Widget w1, w2;
+
+ parent = fontpath->parent;
+ node = parent->child;
+ if (!node->next->next)
+ return;
+ if (strcmp(XtName(w), "up") == 0) {
+ if (node == fontpath)
+ while (node->next->next)
+ node = node->next;
+ else
+ while (node && node->next != fontpath)
+ node = node->next;
+ }
+ else {
+ if (fontpath->next->next)
+ node = fontpath->next;
+ /* else is already correct */
+ }
+
+ w1 = node->data->files.text;
+ w2 = fontpath->data->files.text;
+
+ XtVaGetValues(w1, XtNstring, &t1, NULL);
+ XtVaGetValues(w2, XtNstring, &t2, NULL);
+ t1 = XtNewString(t1);
+ XtVaSetValues(w1, XtNstring, t2, NULL);
+ XtVaSetValues(w2, XtNstring, t1, NULL);
+ XtFree(t1);
+}
+
+
+/* ModulePath */
+/* Don't need to set the update tree field, as it is already set
+ * as the destroy field */
+static void
+CreateModulePath(TreeNode *modulepath, char *path)
+{
+ TreeNode *prev = NULL, *node;
+ Widget w;
+
+ if (path == NULL) {
+ if (XF86Module_path) {
+ path = XtNewString(XF86Module_path);
+ if (XF86Config->conf_files && XF86Config->conf_files->file_modulepath) {
+ XtFree(XF86Config->conf_files->file_modulepath);
+ XF86Config->conf_files->file_modulepath = XtNewString(path);
+ }
+ }
+ else if (XF86Config->conf_files && XF86Config->conf_files->file_modulepath)
+ path = XtNewString(XF86Config->conf_files->file_modulepath);
+ }
+ else {
+ path = XtNewString(path);
+ if ((prev = modulepath->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+ }
+
+ if (path) {
+ char *s;
+
+ for (s = strtok(path, ","); s != NULL; s = strtok(NULL, ",")) {
+ node = NewNode(modulepath, NULL, NULL, modulepath->node, NULL);
+ node->destroy = ModulePathChanged;
+ w = CreateModulePathField(node, s, False);
+ if (modulepath->child == NULL)
+ modulepath->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ }
+ XtFree(path);
+ }
+
+ node = NewNode(modulepath, NULL, NULL, modulepath->node, NULL);
+ w = CreateModulePathField(node, "", True);
+ if (modulepath->child == NULL)
+ modulepath->child = node;
+ else
+ prev->next = node;
+}
+
+static Widget
+CreateModulePathField(TreeNode *modulepath, char *value, Bool addnew)
+{
+ Widget box, command, text;
+ TreeData *data;
+
+ box = XtVaCreateWidget("modulepath", formWidgetClass, tree,
+ XtNtreeParent, modulepath->treeParent, NULL, 0);
+ modulepath->node = box;
+ if (!addnew) {
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback,
+ (XtPointer)modulepath);
+ text = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, value, NULL, 0);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box, NULL, 0);
+ XtAddCallback(command, XtNcallback, NewModulePathCallback,
+ (XtPointer)modulepath);
+ text = XtVaCreateManagedWidget("valueNew", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, value, NULL, 0);
+ }
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->files.text = text;
+ modulepath->data = data;
+
+ if (modulepath->treeParent && XtIsRealized(modulepath->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+
+ return (box);
+}
+
+static void
+ModulePathChanged(TreeNode *node)
+{
+ TreeNode *parent = node->parent;
+ char *modulepath = NULL, *str;
+ Arg args[1];
+ int pos = 0, len;
+
+ /* last node is the "new" */
+ for (node = parent->child; node->next != NULL; node = node->next) {
+ if (pos)
+ modulepath[pos++] = ',';
+ XtSetArg(args[0], XtNstring, &str);
+ XtGetValues(node->data->files.text, args, 1);
+ len = strlen(str) + 2;
+ modulepath = XtRealloc(modulepath, pos + len);
+ strcpy(modulepath + pos, str);
+ pos += len - 2;
+ }
+
+ if (XF86Config->conf_files->file_modulepath)
+ XtFree(XF86Config->conf_files->file_modulepath);
+ XF86Config->conf_files->file_modulepath = modulepath;
+}
+
+static void
+NewModulePathCallback(Widget unused, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *modulepath, *node = (TreeNode*)user_data;
+ Arg args[1];
+ char *str;
+
+ XtSetArg(args[0], XtNstring, &str);
+ XtGetValues(node->data->files.text, args, 1);
+ if (*str == '\0')
+ return;
+
+ modulepath = node->parent;
+ DeleteNode(node);
+ CreateModulePath(modulepath, str);
+
+ ModulePathChanged(modulepath->child);
+ RelayoutTree();
+}
+
+/* Module */
+static void
+CreateModule(TreeNode *module, XF86LoadPtr load)
+{
+ TreeNode *prev, *node;
+ TreeData *data;
+
+ if ((prev = module->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (load) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->module.load = load;
+ node = NewNode(module, NULL, NULL, module->node, data);
+ node->destroy = ModuleDestroy;
+ CreateModuleField(node, False);
+ if (module->child == NULL)
+ module->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ load = (XF86LoadPtr)(load->list.next);
+ }
+
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(module, NULL, NULL, module->node, data);
+ CreateModuleField(node, True);
+ if (module->child == NULL)
+ module->child = node;
+ else
+ prev->next = node;
+}
+
+static void
+CreateModuleField(TreeNode *node, Bool addnew)
+{
+ Widget box, command, label;
+
+ box = XtVaCreateWidget("module", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ XF86OptionPtr *options;
+ XF86LoadPtr load = node->data->module.load;
+
+ options = &(load->load_opt);
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ command = XtCreateManagedWidget("options", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
+ label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, load->load_name, NULL, 0);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, NewModuleCallback, (XtPointer)node);
+ label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ node->data->module.text = label;
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+/*ARGUSED*/
+static void
+ModuleDestroy(TreeNode *node)
+{
+ if (node->data->module.load)
+ xf86removeModule(XF86Config, node->data->module.load);
+}
+
+/*ARGSUSED*/
+static void
+NewModuleCallback(Widget unused, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *module, *node = (TreeNode*)user_data;
+ XF86LoadPtr load;
+ Arg args[1];
+ char *label;
+
+ XtSetArg(args[0], XtNstring, &label);
+ XtGetValues(node->data->module.text, args, 1);
+ if (*label == '\0')
+ return;
+
+ module = node->parent;
+ DeleteNode(node);
+ load = (XF86LoadPtr)XtCalloc(1, sizeof(XF86LoadRec));
+ load->load_name = XtNewString(label);
+ XF86Config->conf_modules->mod_load_lst =
+ xf86addModule(XF86Config->conf_modules->mod_load_lst, load);
+
+ CreateModule(module, load);
+ RelayoutTree();
+}
+
+/* Modes */
+static void
+CreateModes(TreeNode *parent, XF86ConfModesPtr modes)
+{
+ TreeNode *node, *prev;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (modes) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->modes.modes = modes;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = ModesDestroy;
+ CreateModesField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+
+ modes = (XF86ConfModesPtr)(modes->list.next);
+ }
+
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ CreateModesField(node, True);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+}
+
+static void
+CreateModesField(TreeNode *node, Bool addnew)
+{
+ Widget box, command, label;
+
+ box = XtVaCreateWidget("modes", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ XF86ConfModesPtr modes = node->data->modes.modes;
+
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ label = XtVaCreateManagedWidget("mode", toggleWidgetClass, box,
+ XtNlabel, modes->modes_identifier,
+ XtNstate, True,
+ NULL, 0);
+ node->toggle = label;
+ XtAddCallback(label, XtNcallback, ToggleCallback, (XtPointer)node);
+ CreateModesModeLine(node, node->data->modes.modes->mon_modeline_lst);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, NewModesCallback, (XtPointer)node);
+ label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ node->data->modes.text = label;
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+/*ARGUSED*/
+static void
+ModesDestroy(TreeNode *node)
+{
+ if (node->data->modes.modes) {
+ int i;
+ TreeNode *mon = monitorTree->child;
+
+ /* last one is the "new" entry */
+ while (mon && mon->next) {
+ /* UseModes is the second entry */
+ TreeNode *mod = mon->child->next->child;
+ CompositeWidget composite;
+
+ while (mod && mod->next) {
+ TreeNode *next = mod->next;
+
+ if (mod && strcmp(mod->data->modeslink.modeslink->ml_modes_str,
+ node->data->modes.modes->modes_identifier) == 0)
+ /* Needs to do string comparison because may be deleting
+ * a "test" Modes section, with no Modelines.
+ */
+ DeleteNode(mod);
+ mod = next;
+ }
+ composite = (CompositeWidget)mod->data->modeslink.menu;
+
+ for (i = 0; i < composite->composite.num_children; ++i)
+ if (strcmp(XtName(composite->composite.children[i]),
+ node->data->modes.modes->modes_identifier) == 0)
+ XtDestroyWidget(composite->composite.children[i]);
+
+ mon = mon->next;
+ }
+
+ xf86removeModes(XF86Config, node->data->modes.modes);
+ }
+}
+
+/*ARGSUSED*/
+static void
+NewModesCallback(Widget unused, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfModesPtr modes;
+ Arg args[1];
+ char *label;
+
+ XtSetArg(args[0], XtNstring, &label);
+ XtGetValues(node->data->modes.text, args, 1);
+ if (*label == '\0')
+ return;
+
+ parent = node->parent;
+ DeleteNode(node);
+ modes = (XF86ConfModesPtr)XtCalloc(1, sizeof(XF86ConfModesRec));
+ modes->modes_identifier = XtNewString(label);
+ XF86Config->conf_modes_lst =
+ xf86addModes(XF86Config->conf_modes_lst, modes);
+
+ {
+ TreeNode *mon = monitorTree->child;
+ Widget sme;
+
+ /* last one is the "new" entry */
+ while (mon && mon->next) {
+ /* UseModes is the second entry */
+ TreeNode *mod = mon->child->next->child;
+
+ while (mod && mod->next)
+ mod = mod->next;
+
+ sme = XtCreateManagedWidget(modes->modes_identifier,
+ smeBSBObjectClass,
+ mod->data->modeslink.menu, NULL, 0);
+ XtAddCallback(sme, XtNcallback, NewMonitorModesCallback,
+ (XtPointer)mod);
+
+ mon = mon->next;
+ }
+ }
+
+ CreateModes(parent, modes);
+ RelayoutTree();
+}
+
+static void
+CreateModesModeLine(TreeNode *parent, XF86ConfModeLinePtr modeline)
+{
+ TreeNode *node, *prev;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (modeline) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->modeline.modeline = modeline;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = ModesModeLineDestroy;
+ CreateModeLineField(node, False, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ modeline = (XF86ConfModeLinePtr)(modeline->list.next);
+ }
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ CreateModeLineField(node, True, False);
+}
+
+/* This function should allow creating modelines for the
+ Mode and Monitor section */
+static void
+CreateModeLineField(TreeNode *node, Bool addnew, Bool monitor)
+{
+ Widget box, command;
+ char buf[512], tmp[32];
+
+ box = XtVaCreateWidget("modeline", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ XF86ConfModeLinePtr mod = node->data->modeline.modeline;
+
+ command = XtCreateManagedWidget("remove", commandWidgetClass,
+ box, NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, mod->ml_identifier, NULL, 0);
+
+ XmuSnprintf(buf, sizeof(buf), "%g %d %d %d %d %d %d %d %d",
+ mod->ml_clock / 1000., mod->ml_hdisplay, mod->ml_hsyncstart,
+ mod->ml_hsyncend, mod->ml_htotal, mod->ml_vdisplay,
+ mod->ml_vsyncstart, mod->ml_vsyncend, mod->ml_vtotal);
+ if (mod->ml_flags & XF86CONF_INTERLACE)
+ strcat(buf, " interlace");
+ if (mod->ml_flags & XF86CONF_PHSYNC)
+ strcat(buf, " +hsync");
+ if (mod->ml_flags & XF86CONF_NHSYNC)
+ strcat(buf, " -hsync");
+ if (mod->ml_flags & XF86CONF_PVSYNC)
+ strcat(buf, " +vsync");
+ if (mod->ml_flags & XF86CONF_NVSYNC)
+ strcat(buf, " -vsync");
+ if (mod->ml_flags & XF86CONF_CSYNC)
+ strcat(buf, " composite");
+ if (mod->ml_flags & XF86CONF_PCSYNC)
+ strcat(buf, " +csync");
+ if (mod->ml_flags & XF86CONF_NCSYNC)
+ strcat(buf, " -csync");
+ if (mod->ml_flags & XF86CONF_DBLSCAN)
+ strcat(buf, " doublescan");
+ if (mod->ml_flags & XF86CONF_BCAST)
+ strcat(buf, " bcast");
+ if (mod->ml_flags & XF86CONF_HSKEW) {
+ XmuSnprintf(tmp, sizeof(tmp), " hskew %d", mod->ml_hskew);
+ strcat(buf, tmp);
+ }
+ if (mod->ml_flags & XF86CONF_VSCAN) {
+ XmuSnprintf(tmp, sizeof(tmp), " vscan %d", mod->ml_vscan);
+ strcat(buf, tmp);
+ }
+ if (mod->ml_flags & XF86CONF_CUSTOM)
+ strcat(buf, " custom");
+ node->data->modeline.value =
+ XtVaCreateManagedWidget("modeline", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf, NULL, 0);
+ }
+ else {
+ *buf = '\0';
+ command = XtCreateManagedWidget("new", commandWidgetClass,
+ box, NULL, 0);
+ XtAddCallback(command, XtNcallback, monitor ?
+ NewMonitorModeLineCallback : NewModesModeLineCallback,
+ (XtPointer)node);
+ node->data->modeline.text =
+ XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit, NULL, 0);
+ node->data->modeline.value =
+ XtVaCreateManagedWidget("modelineNew", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit, NULL, 0);
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+/*ARGUSED*/
+static void
+ModesModeLineDestroy(TreeNode *node)
+{
+ if (node->data->modeline.modeline)
+ xf86removeModesModeLine(node->parent->data->modes.modes,
+ node->data->modeline.modeline);
+}
+
+/*ARGSUSED*/
+static void
+NewModesModeLineCallback(Widget unused, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfModeLinePtr modeline;
+ Arg args[1];
+ char *ident, *value;
+
+ XtSetArg(args[0], XtNstring, &ident);
+ XtGetValues(node->data->modeline.text, args, 1);
+ XtSetArg(args[0], XtNstring, &value);
+ XtGetValues(node->data->modeline.value, args, 1);
+ if (*ident == '\0' || *value == '\0')
+ return;
+
+ parent = node->parent;
+ DeleteNode(node);
+ modeline = ParseModeLine(ident, value);
+ parent->data->modes.modes->mon_modeline_lst =
+ xf86addModeLine(parent->data->modes.modes->mon_modeline_lst, modeline);
+
+ CreateModesModeLine(parent, modeline);
+ RelayoutTree();
+}
+
+static XF86ConfModeLinePtr
+ParseModeLine(char *identifier, char *modeline)
+{
+ XF86ConfModeLinePtr ml = (XF86ConfModeLinePtr)
+ XtCalloc(1, sizeof(XF86ConfModeLineRec));
+ char *s, *ptr = modeline;
+
+ /* Identifier */
+ ml->ml_identifier = XtNewString(identifier);
+
+ ml->ml_clock = (int)(strtod(ptr, &ptr) * 1000.0 + 0.5);
+ while (*ptr && isspace(*ptr)) ++ptr;
+
+ ml->ml_hdisplay = strtol(ptr, &ptr, 10);
+ while (*ptr && isspace(*ptr)) ++ptr;
+
+ ml->ml_hsyncstart = strtol(ptr, &ptr, 10);
+ while (*ptr && isspace(*ptr)) ++ptr;
+
+ ml->ml_hsyncend = strtol(ptr, &ptr, 10);
+ while (*ptr && isspace(*ptr)) ++ptr;
+
+ ml->ml_htotal = strtol(ptr, &ptr, 10);
+ while (*ptr && isspace(*ptr)) ++ptr;
+
+ ml->ml_vdisplay = strtol(ptr, &ptr, 10);
+ while (*ptr && isspace(*ptr)) ++ptr;
+
+ ml->ml_vsyncstart = strtol(ptr, &ptr, 10);
+ while (*ptr && isspace(*ptr)) ++ptr;
+
+ ml->ml_vsyncend = strtol(ptr, &ptr, 10);
+ while (*ptr && isspace(*ptr)) ++ptr;
+
+ ml->ml_vtotal = strtol(ptr, &ptr, 10);
+ while (*ptr && isspace(*ptr)) ++ptr;
+
+ s = ptr;
+ while (*s) {
+ *s = tolower(*s);
+ ++s;
+ }
+ s = ptr;
+
+ while (*ptr) {
+ while (*s && isspace(*s))
+ s++;
+ ptr = s;
+ while (*s && !isspace(*s))
+ s++;
+
+ if (s != ptr) {
+ Bool done = *s == '\0';
+
+ *s = '\0';
+ if (strcmp(ptr, "interlace") == 0)
+ ml->ml_flags |= XF86CONF_INTERLACE;
+ else if (strcmp(ptr, "+hsync") == 0)
+ ml->ml_flags |= XF86CONF_PHSYNC;
+ else if (strcmp(ptr, "-hsync") == 0)
+ ml->ml_flags |= XF86CONF_NHSYNC;
+ else if (strcmp(ptr, "+vsync") == 0)
+ ml->ml_flags |= XF86CONF_PVSYNC;
+ else if (strcmp(ptr, "-vsync") == 0)
+ ml->ml_flags |= XF86CONF_NVSYNC;
+ else if (strcmp(ptr, "composite") == 0)
+ ml->ml_flags |= XF86CONF_CSYNC;
+ else if (strcmp(ptr, "+csync") == 0)
+ ml->ml_flags |= XF86CONF_PCSYNC;
+ else if (strcmp(ptr, "-csync") == 0)
+ ml->ml_flags |= XF86CONF_NCSYNC;
+ else if (strcmp(ptr, "doublescan") == 0)
+ ml->ml_flags |= XF86CONF_DBLSCAN;
+ else if (strcmp(ptr, "bcast") == 0)
+ ml->ml_flags |= XF86CONF_BCAST;
+ else if (strcmp(ptr, "hskew") == 0) {
+ ++s;
+ while (*s && isspace(*s))
+ ++s;
+ ptr = s;
+ while (*s && !isspace(*s))
+ ++s;
+ if (ptr != s) {
+ ml->ml_hskew = strtol(ptr, &s, 10);
+ ml->ml_flags |= XF86CONF_HSKEW;
+ --s;
+ }
+ }
+ else if (strcmp(ptr, "vscan") == 0) {
+ ++s;
+ while (*s && isspace(*s))
+ ++s;
+ ptr = s;
+ while (*s && !isspace(*s))
+ ++s;
+ if (ptr != s) {
+ ml->ml_vscan = strtol(ptr, &s, 10);
+ ml->ml_flags |= XF86CONF_VSCAN;
+ --s;
+ }
+ }
+ else if (strcmp(ptr, "custom") == 0)
+ ml->ml_flags |= XF86CONF_CUSTOM;
+ ++s;
+ if (done)
+ break;
+ ptr = s;
+ }
+ }
+
+ return (ml);
+}
+
+/* VideoAdpator */
+static void
+CreateVideoAdaptor(TreeNode *parent, XF86ConfVideoAdaptorPtr video)
+{
+ TreeNode *node, *prev;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (video) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->video.video = video;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = VideoAdaptorDestroy;
+ node->update = VideoAdaptorUpdate;
+ CreateVideoAdaptorField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+
+ video = (XF86ConfVideoAdaptorPtr)(video->list.next);
+ }
+
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ CreateVideoAdaptorField(node, True);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+}
+
+static void
+CreateVideoAdaptorField(TreeNode *node, Bool addnew)
+{
+ Widget box, command, label;
+
+ box = XtVaCreateWidget("video", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ char *str;
+ TreeNode *port;
+ XF86ConfVideoAdaptorPtr video = node->data->video.video;
+
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ command = XtCreateManagedWidget("options", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, OptionsCallback,
+ (XtPointer)&(video->va_option_lst));
+ label = XtVaCreateManagedWidget("adaptor", labelWidgetClass, box,
+ XtNlabel, video->va_identifier,
+ NULL, 0);
+
+ XtCreateManagedWidget("vendorL", labelWidgetClass, box, NULL, 0);
+ str = video->va_vendor ? video->va_vendor : "";
+ node->data->video.vendor =
+ XtVaCreateManagedWidget("vendor", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("boardL", labelWidgetClass, box, NULL, 0);
+ str = video->va_board ? video->va_board : "";
+ node->data->video.board =
+ XtVaCreateManagedWidget("board", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("busidL", labelWidgetClass, box, NULL, 0);
+ str = video->va_busid ? video->va_busid : "";
+ node->data->video.busid =
+ XtVaCreateManagedWidget("busid", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("driverL", labelWidgetClass, box, NULL, 0);
+ str = video->va_driver ? video->va_driver : "";
+ node->data->video.driver =
+ XtVaCreateManagedWidget("driver", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ label = XtVaCreateManagedWidget("VideoPort", toggleWidgetClass, tree,
+ XtNstate, True,
+ XtNtreeParent, box,
+ NULL, 0);
+ port = NewNode(node, label, label, node->node, NULL);
+ node->child = port;
+ CreateVideoPort(port, video->va_port_lst);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, NewVideoAdaptorCallback,
+ (XtPointer)node);
+ label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ node->data->video.text = label;
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+/*ARGUSED*/
+static void
+VideoAdaptorDestroy(TreeNode *node)
+{
+ if (node->data->video.video) {
+ int i;
+ TreeNode *scrn = screenTree->child;
+
+ /* last one is the "new" entry */
+ while (scrn && scrn->next) {
+ /* VideoAdator is the first entry */
+ TreeNode *ad = scrn->child->child;
+ CompositeWidget composite;
+
+ while (ad && ad->next) {
+ TreeNode *next = ad->next;
+
+ if (ad && strcmp(ad->data->adaptorlink.adaptorlink->al_adaptor_str,
+ node->data->video.video->va_identifier) == 0)
+ DeleteNode(ad);
+ ad = next;
+ }
+ composite = (CompositeWidget)ad->data->adaptorlink.menu;
+
+ for (i = 0; i < composite->composite.num_children; ++i)
+ if (strcmp(XtName(composite->composite.children[i]),
+ node->data->video.video->va_identifier) == 0)
+ XtDestroyWidget(composite->composite.children[i]);
+
+ scrn = scrn->next;
+ }
+
+ xf86removeVideoAdaptor(XF86Config, node->data->video.video);
+ }
+}
+
+/*ARGSUSED*/
+static void
+NewVideoAdaptorCallback(Widget unused, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfVideoAdaptorPtr video;
+ Arg args[1];
+ char *label;
+
+ XtSetArg(args[0], XtNstring, &label);
+ XtGetValues(node->data->video.text, args, 1);
+ if (*label == '\0')
+ return;
+
+ parent = node->parent;
+ DeleteNode(node);
+ video = (XF86ConfVideoAdaptorPtr)
+ XtCalloc(1, sizeof(XF86ConfVideoAdaptorRec));
+ video->va_identifier = XtNewString(label);
+ XF86Config->conf_videoadaptor_lst =
+ xf86addVideoAdaptor(XF86Config->conf_videoadaptor_lst, video);
+
+ {
+ TreeNode *scrn = screenTree->child;
+ Widget sme;
+
+ /* last one is the "new" entry */
+ while (scrn && scrn->next) {
+ /* VideoAdaptor is the first entry */
+ TreeNode *ad = scrn->child->child;
+
+ while (ad && ad->next)
+ ad = ad->next;
+
+ sme = XtCreateManagedWidget(video->va_identifier,
+ smeBSBObjectClass,
+ ad->data->adaptorlink.menu, NULL, 0);
+ XtAddCallback(sme, XtNcallback, NewScreenAdaptorCallback,
+ (XtPointer)ad);
+
+ scrn = scrn->next;
+ }
+ }
+
+ CreateVideoAdaptor(parent, video);
+ RelayoutTree();
+}
+
+static void
+VideoAdaptorUpdate(TreeNode *node)
+{
+ char *str;
+
+ /* vendor */
+ XtVaGetValues(node->data->video.vendor, XtNstring, &str, NULL, 0);
+ XtFree(node->data->video.video->va_vendor);
+ if (*str)
+ node->data->video.video->va_vendor = XtNewString(str);
+ else
+ node->data->video.video->va_vendor = NULL;
+
+ /* board */
+ XtVaGetValues(node->data->video.board, XtNstring, &str, NULL, 0);
+ XtFree(node->data->video.video->va_board);
+ if (*str)
+ node->data->video.video->va_board = XtNewString(str);
+ else
+ node->data->video.video->va_board = NULL;
+
+ /* busid */
+ XtVaGetValues(node->data->video.busid, XtNstring, &str, NULL, 0);
+ XtFree(node->data->video.video->va_busid);
+ if (*str)
+ node->data->video.video->va_busid = XtNewString(str);
+ else
+ node->data->video.video->va_busid = NULL;
+
+ /* driver */
+ XtVaGetValues(node->data->video.driver, XtNstring, &str, NULL, 0);
+ XtFree(node->data->video.video->va_driver);
+ if (*str)
+ node->data->video.video->va_driver = XtNewString(str);
+ else
+ node->data->video.video->va_driver = NULL;
+}
+
+static void
+CreateVideoPort(TreeNode *parent, XF86ConfVideoPortPtr port)
+{
+ TreeNode *prev, *node;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (port) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->port.port = port;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = VideoPortDestroy;
+ CreateVideoPortField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ port = (XF86ConfVideoPortPtr)(port->list.next);
+ }
+
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ CreateVideoPortField(node, True);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+}
+
+static void
+CreateVideoPortField(TreeNode *node, Bool addnew)
+{
+ Widget box, command, label;
+
+ box = XtVaCreateWidget("port", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ XF86OptionPtr *options;
+ XF86ConfVideoPortPtr port = node->data->port.port;
+
+ options = &(port->vp_option_lst);
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ command = XtCreateManagedWidget("options", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
+ label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, port->vp_identifier, NULL, 0);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, NewVideoPortCallback, (XtPointer)node);
+ label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ node->data->port.text = label;
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+/*ARGUSED*/
+static void
+VideoPortDestroy(TreeNode *node)
+{
+ if (node->data->port.port)
+ xf86removeVideoPort(node->parent->parent->data->video.video,
+ node->data->port.port);
+}
+
+/*ARGSUSED*/
+static void
+NewVideoPortCallback(Widget unused, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *video, *node = (TreeNode*)user_data;
+ XF86ConfVideoPortPtr port;
+ Arg args[1];
+ char *label;
+
+ XtSetArg(args[0], XtNstring, &label);
+ XtGetValues(node->data->port.text, args, 1);
+ if (*label == '\0')
+ return;
+
+ video = node->parent->parent;
+ DeleteNode(node);
+ port = (XF86ConfVideoPortPtr)XtCalloc(1, sizeof(XF86ConfVideoPortRec));
+ port->vp_identifier = XtNewString(label);
+ video->data->video.video->va_port_lst =
+ xf86addVideoPort(video->data->video.video->va_port_lst, port);
+
+ CreateVideoPort(video, port);
+ RelayoutTree();
+}
+
+/* Monitor */
+static void
+CreateMonitor(TreeNode *parent, XF86ConfMonitorPtr mon)
+{
+ TreeNode *prev, *node;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (mon) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->monitor.monitor = mon;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = MonitorDestroy;
+ node->update = MonitorUpdate;
+ CreateMonitorField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ mon = (XF86ConfMonitorPtr)(mon->list.next);
+ }
+
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ CreateMonitorField(node, True);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+}
+
+static void
+CreateMonitorField(TreeNode *node, Bool addnew)
+{
+ Widget box, command, label;
+
+ box = XtVaCreateWidget("monitor", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ char *str, buf[256];
+ XF86OptionPtr *options;
+ XF86ConfMonitorPtr mon = node->data->monitor.monitor;
+ Widget useModes;
+ TreeNode *modeline, *modes, *prev;
+
+ options = &(mon->mon_option_lst);
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ command = XtCreateManagedWidget("options", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
+ label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, mon->mon_identifier, NULL, 0);
+
+ XtCreateManagedWidget("vendorL", labelWidgetClass, box, NULL, 0);
+ str = mon->mon_vendor ? mon->mon_vendor : "";
+ node->data->monitor.vendor =
+ XtVaCreateManagedWidget("vendor", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("modelnameL", labelWidgetClass, box, NULL, 0);
+ str = mon->mon_modelname ? mon->mon_modelname : "";
+ node->data->monitor.model =
+ XtVaCreateManagedWidget("modelname", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("widthL", labelWidgetClass, box, NULL, 0);
+ if (mon->mon_width)
+ XmuSnprintf(buf, sizeof(buf), "%d", mon->mon_width);
+ else
+ *buf = '\0';
+ node->data->monitor.width =
+ XtVaCreateManagedWidget("width", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("heightL", labelWidgetClass, box, NULL, 0);
+ if (mon->mon_height)
+ XmuSnprintf(buf, sizeof(buf), "%d", mon->mon_height);
+ else
+ *buf = '\0';
+ node->data->monitor.height =
+ XtVaCreateManagedWidget("height", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("hsyncL", labelWidgetClass, box, NULL, 0);
+ if (mon->mon_n_hsync > 0)
+ parser_range_to_string(buf, &(mon->mon_hsync[0]),
+ mon->mon_n_hsync);
+ else
+ *buf = '\0';
+ node->data->monitor.hsync =
+ XtVaCreateManagedWidget("hsync", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("vrefreshL", labelWidgetClass, box, NULL, 0);
+ if (mon->mon_n_vrefresh > 0)
+ parser_range_to_string(buf, &(mon->mon_vrefresh[0]),
+ mon->mon_n_vrefresh);
+ else
+ *buf = '\0';
+ node->data->monitor.vrefresh =
+ XtVaCreateManagedWidget("vrefresh", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("gammaRedL", labelWidgetClass, box, NULL, 0);
+ if (mon->mon_gamma_red)
+ XmuSnprintf(buf, sizeof(buf), "%g", mon->mon_gamma_red);
+ else
+ *buf = '\0';
+ node->data->monitor.gammaRed =
+ XtVaCreateManagedWidget("gammaRed", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("gammaGreenL", labelWidgetClass, box, NULL, 0);
+ if (mon->mon_gamma_green)
+ XmuSnprintf(buf, sizeof(buf), "%g", mon->mon_gamma_green);
+ else
+ *buf = '\0';
+ node->data->monitor.gammaGreen =
+ XtVaCreateManagedWidget("gammaGreen", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("gammaBlueL", labelWidgetClass, box, NULL, 0);
+ if (mon->mon_gamma_blue)
+ XmuSnprintf(buf, sizeof(buf), "%g", mon->mon_gamma_blue);
+ else
+ *buf = '\0';
+ node->data->monitor.gammaBlue =
+ XtVaCreateManagedWidget("gammaBlue", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ if ((prev = node->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+ command = XtVaCreateManagedWidget("ModeLine", toggleWidgetClass, tree,
+ XtNstate, True,
+ XtNtreeParent, box, NULL, 0);
+ modeline = NewNode(node, command, command, node->node, NULL);
+ CreateMonitorModeLine(modeline,
+ node->data->monitor.monitor->mon_modeline_lst);
+ if (prev == NULL)
+ prev = node->child = modeline;
+ else {
+ prev->next = modeline;
+ prev = prev->next;
+ }
+
+ useModes = XtVaCreateManagedWidget("UseModes", toggleWidgetClass, tree,
+ XtNstate, True,
+ XtNtreeParent, box, NULL, 0);
+ prev->next = modes = NewNode(node, useModes, useModes, node->node, NULL);
+ CreateMonitorModes(modes,
+ node->data->monitor.monitor->mon_modes_sect_lst);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, NewMonitorCallback, (XtPointer)node);
+ label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ node->data->monitor.text = label;
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+static void
+MonitorDestroy(TreeNode *node)
+{
+ int i;
+ TreeNode *sc = screenTree;
+
+ for (i = 0; i < computer.num_devices; i++)
+ if ((XF86ConfMonitorPtr)(computer.devices[i]->config) ==
+ node->data->monitor.monitor) {
+ config = computer.devices[i]->widget;
+ RemoveDeviceCallback(NULL, NULL, NULL);
+ }
+
+ if (sc) {
+ TreeNode *prev;
+
+ sc = prev = sc->child;
+ while (sc->next) {
+ TreeNode *next = sc->next;
+
+ if (sc->data->screen.screen->scrn_monitor ==
+ node->data->monitor.monitor) {
+ XtDestroyWidget(sc->node);
+
+ if (sc->child)
+ DestroyTree(sc->child);
+ if (sc->data)
+ XtFree((XtPointer)sc->data);
+ XtFree((XtPointer)sc);
+
+ if (sc == screenTree->child)
+ sc = prev = next = screenTree->child = next;
+ else
+ prev->next = sc = next;
+ continue;
+ }
+ prev = sc;
+ sc = next;
+ }
+ }
+}
+
+static void
+NewMonitorCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfMonitorPtr mon;
+ Arg args[1];
+ char *label;
+
+ XtSetArg(args[0], XtNstring, &label);
+ XtGetValues(node->data->monitor.text, args, 1);
+ if (*label == '\0')
+ return;
+
+ parent = node->parent;
+ DeleteNode(node);
+ mon = (XF86ConfMonitorPtr)XtCalloc(1, sizeof(XF86ConfMonitorRec));
+ mon->mon_identifier = XtNewString(label);
+ XF86Config->conf_monitor_lst =
+ xf86addMonitor(XF86Config->conf_monitor_lst, mon);
+
+ CreateMonitor(parent, mon);
+
+ RelayoutTree();
+}
+
+static void
+MonitorUpdate(TreeNode *node)
+{
+ char *str;
+
+ /* vendor */
+ XtVaGetValues(node->data->monitor.vendor, XtNstring, &str, NULL, 0);
+ XtFree(node->data->monitor.monitor->mon_vendor);
+ if (*str)
+ node->data->monitor.monitor->mon_vendor = XtNewString(str);
+ else
+ node->data->monitor.monitor->mon_vendor = NULL;
+
+ /* model */
+ XtVaGetValues(node->data->monitor.model, XtNstring, &str, NULL, 0);
+ XtFree(node->data->monitor.monitor->mon_modelname);
+ if (*str)
+ node->data->monitor.monitor->mon_modelname = XtNewString(str);
+ else
+ node->data->monitor.monitor->mon_modelname = NULL;
+
+ /* width */
+ XtVaGetValues(node->data->monitor.width, XtNstring, &str, NULL, 0);
+ node->data->monitor.monitor->mon_width = strtoul(str, NULL, 0);
+
+ /* height */
+ XtVaGetValues(node->data->monitor.height, XtNstring, &str, NULL, 0);
+ node->data->monitor.monitor->mon_height = strtoul(str, NULL, 0);
+
+ /* hsync */
+ XtVaGetValues(node->data->monitor.hsync, XtNstring, &str, NULL, 0);
+ node->data->monitor.monitor->mon_n_hsync =
+ string_to_parser_range(str,
+ &(node->data->monitor.monitor->mon_hsync[0]),
+ CONF_MAX_HSYNC);
+
+ /* vrefresh */
+ XtVaGetValues(node->data->monitor.vrefresh, XtNstring, &str, NULL, 0);
+ node->data->monitor.monitor->mon_n_vrefresh =
+ string_to_parser_range(str,
+ &(node->data->monitor.monitor->mon_vrefresh[0]),
+ CONF_MAX_VREFRESH);
+
+ /* gammaRed */
+ XtVaGetValues(node->data->monitor.gammaRed, XtNstring, &str, NULL, 0);
+ node->data->monitor.monitor->mon_gamma_red = strtod(str, NULL);
+
+ /* gammaGreen */
+ XtVaGetValues(node->data->monitor.gammaGreen, XtNstring, &str, NULL, 0);
+ node->data->monitor.monitor->mon_gamma_green = strtod(str, NULL);
+
+ /* gammaBlue */
+ XtVaGetValues(node->data->monitor.gammaBlue, XtNstring, &str, NULL, 0);
+ node->data->monitor.monitor->mon_gamma_blue = strtod(str, NULL);
+}
+
+static void
+CreateMonitorModeLine(TreeNode *parent, XF86ConfModeLinePtr modeline)
+{
+ TreeNode *node, *prev;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (modeline) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->modeline.modeline = modeline;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = MonitorModeLineDestroy;
+ CreateModeLineField(node, False, True);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ modeline = (XF86ConfModeLinePtr)(modeline->list.next);
+ }
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ CreateModeLineField(node, True, True);
+}
+
+/*ARGUSED*/
+static void
+MonitorModeLineDestroy(TreeNode *node)
+{
+ if (node->data->modeline.modeline)
+ xf86removeMonitorModeLine(node->parent->parent->data->monitor.monitor,
+ node->data->modeline.modeline);
+}
+
+/*ARGSUSED*/
+static void
+NewMonitorModeLineCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfModeLinePtr modeline;
+ Arg args[1];
+ char *ident, *value;
+
+ XtSetArg(args[0], XtNstring, &ident);
+ XtGetValues(node->data->modeline.text, args, 1);
+ XtSetArg(args[0], XtNstring, &value);
+ XtGetValues(node->data->modeline.value, args, 1);
+ if (*ident == '\0' || *value == '\0')
+ return;
+
+ parent = node->parent;
+ DeleteNode(node);
+ modeline = ParseModeLine(ident, value);
+ parent->parent->data->monitor.monitor->mon_modeline_lst =
+ xf86addModeLine(parent->parent->data->monitor.monitor->mon_modeline_lst,
+ modeline);
+
+ CreateMonitorModeLine(parent, modeline);
+ RelayoutTree();
+}
+
+static void
+CreateMonitorModes(TreeNode *parent, XF86ConfModesLinkPtr lnk)
+{
+ TreeNode *node, *prev;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (lnk) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->modeslink.modeslink = lnk;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = MonitorModesLinkDestroy;
+ CreateMonitorModesField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ lnk = (XF86ConfModesLinkPtr)(lnk->list.next);
+ }
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ CreateMonitorModesField(node, True);
+}
+
+static void
+CreateMonitorModesField(TreeNode *node, Bool addnew)
+{
+ Widget box, command, label;
+
+ box = XtVaCreateWidget("modes", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ XF86ConfModesLinkPtr lnk = node->data->modeslink.modeslink;
+
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ label = XtVaCreateManagedWidget("mode", labelWidgetClass, box,
+ XtNlabel, lnk->ml_modes_str, NULL, 0);
+ }
+ else {
+ Widget sme;
+ XF86ConfModesPtr ptr = XF86Config->conf_modes_lst;
+
+ command = XtVaCreateManagedWidget("new", menuButtonWidgetClass, box,
+ XtNmenuName, "modesMenu", NULL, 0);
+ node->data->modeslink.menu =
+ XtVaCreatePopupShell("modesMenu", simpleMenuWidgetClass, box,
+ XtNleftMargin, 1, XtNrightMargin, 1,
+ XtNtopMargin, 1, XtNbottomMargin, 1,
+ NULL, 0);
+ while (ptr) {
+ sme = XtCreateManagedWidget(ptr->modes_identifier, smeBSBObjectClass,
+ node->data->modeslink.menu, NULL, 0);
+ XtAddCallback(sme, XtNcallback, NewMonitorModesCallback,
+ (XtPointer)node);
+ ptr = (XF86ConfModesPtr)(ptr->list.next);
+ }
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+/*ARGUSED*/
+static void
+MonitorModesLinkDestroy(TreeNode *node)
+{
+ if (node->data->modeslink.modeslink)
+ xf86removeMonitorModesLink(node->parent->parent->data->monitor.monitor,
+ node->data->modeslink.modeslink);
+}
+
+/*ARGSUSED*/
+static void
+NewMonitorModesCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfModesLinkPtr link;
+ char *ident = XtName(w);
+
+ parent = node->parent;
+ DeleteNode(node);
+ link = (XF86ConfModesLinkPtr)XtCalloc(1, sizeof(XF86ConfModesLinkRec));
+ link->ml_modes_str = XtNewString(ident);
+ parent->parent->data->monitor.monitor->mon_modes_sect_lst =
+ xf86addModesLink(parent->parent->data->monitor.monitor->mon_modes_sect_lst,
+ link);
+
+ CreateMonitorModes(parent, link);
+ RelayoutTree();
+}
+
+/* Device */
+static void
+CreateDevice(TreeNode *parent, XF86ConfDevicePtr dev)
+{
+ TreeNode *prev, *node;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (dev) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->device.device = dev;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = DeviceDestroy;
+ node->update = DeviceUpdate;
+ CreateDeviceField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ dev = (XF86ConfDevicePtr)(dev->list.next);
+ }
+
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ CreateDeviceField(node, True);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+}
+
+static void
+CreateDeviceField(TreeNode *node, Bool addnew)
+{
+ Widget box, command, label;
+
+ box = XtVaCreateWidget("device", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ int i, tmp, len;
+ char buf[1024], *str;
+ XF86OptionPtr *options;
+ XF86ConfDevicePtr dev = node->data->device.device;
+
+ options = &(dev->dev_option_lst);
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ command = XtCreateManagedWidget("options", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
+ label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, dev->dev_identifier, NULL, 0);
+
+ XtCreateManagedWidget("vendorL", labelWidgetClass, box, NULL, 0);
+ str = dev->dev_vendor ? dev->dev_vendor : "";
+ node->data->device.vendor =
+ XtVaCreateManagedWidget("vendor", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("boardL", labelWidgetClass, box, NULL, 0);
+ str = dev->dev_board ? dev->dev_board : "";
+ node->data->device.board =
+ XtVaCreateManagedWidget("board", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("chipsetL", labelWidgetClass, box, NULL, 0);
+ str = dev->dev_chipset ? dev->dev_chipset : "";
+ node->data->device.chipset =
+ XtVaCreateManagedWidget("chipset", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("busidL", labelWidgetClass, box, NULL, 0);
+ str = dev->dev_busid ? dev->dev_busid : "";
+ node->data->device.busid =
+ XtVaCreateManagedWidget("busid", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("cardL", labelWidgetClass, box, NULL, 0);
+ str = dev->dev_card ? dev->dev_card : "";
+ node->data->device.card =
+ XtVaCreateManagedWidget("card", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("driverL", labelWidgetClass, box, NULL, 0);
+ str = dev->dev_driver ? dev->dev_driver : "";
+ node->data->device.driver =
+ XtVaCreateManagedWidget("driver", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("ramdacL", labelWidgetClass, box, NULL, 0);
+ str = dev->dev_ramdac ? dev->dev_ramdac : "";
+ node->data->device.ramdac =
+ XtVaCreateManagedWidget("ramdac", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("dacSpeedL", labelWidgetClass, box, NULL, 0);
+ if (dev->dev_dacSpeeds[0] > 0) {
+ for (i = len = 0; i < CONF_MAXDACSPEEDS &&
+ dev->dev_dacSpeeds[i] > 0; i++) {
+ tmp = XmuSnprintf(buf + len, sizeof(buf) - len, "%g ",
+ dev->dev_dacSpeeds[i] / 1000.);
+ len += tmp;
+ }
+ }
+ else
+ *buf = '\0';
+ node->data->device.dacSpeed =
+ XtVaCreateManagedWidget("dacSpeed", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("videoRamL", labelWidgetClass, box, NULL, 0);
+ if (dev->dev_videoram)
+ XmuSnprintf(buf, sizeof(buf), "%d", dev->dev_videoram);
+ else
+ *buf = '\0';
+ node->data->device.videoRam =
+ XtVaCreateManagedWidget("videoRam", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("textClockFreqL", labelWidgetClass, box, NULL, 0);
+ if (dev->dev_textclockfreq)
+ XmuSnprintf(buf, sizeof(buf), "%.1f",
+ (double)dev->dev_textclockfreq / 1000.0);
+ else
+ *buf = '\0';
+ node->data->device.textClockFreq =
+ XtVaCreateManagedWidget("textClockFreq", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("biosBaseL", labelWidgetClass, box, NULL, 0);
+ if (dev->dev_bios_base)
+ XmuSnprintf(buf, sizeof(buf), "0x%lx", dev->dev_bios_base);
+ else
+ *buf = '\0';
+ node->data->device.biosBase =
+ XtVaCreateManagedWidget("biosBase", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("memBaseL", labelWidgetClass, box, NULL, 0);
+ if (dev->dev_mem_base)
+ XmuSnprintf(buf, sizeof(buf), "0x%lx", dev->dev_mem_base);
+ else
+ *buf = '\0';
+ node->data->device.memBase =
+ XtVaCreateManagedWidget("memBase", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("ioBaseL", labelWidgetClass, box, NULL, 0);
+ if (dev->dev_io_base)
+ XmuSnprintf(buf, sizeof(buf), "0x%lx", dev->dev_io_base);
+ else
+ *buf = '\0';
+ node->data->device.ioBase =
+ XtVaCreateManagedWidget("ioBase", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("clockChipL", labelWidgetClass, box, NULL, 0);
+ str = dev->dev_clockchip ? dev->dev_clockchip : "";
+ node->data->device.clockChip =
+ XtVaCreateManagedWidget("clockChip", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ *buf = '\0';
+ for (i = len = 0; i < dev->dev_clocks; i++) {
+ tmp = XmuSnprintf(buf + len, sizeof(buf) - len, "%.1f ",
+ (double)dev->dev_clock[i] / 1000.0);
+ len += tmp;
+ }
+ XtCreateManagedWidget("devClockL", labelWidgetClass, box, NULL, 0);
+ node->data->device.devClock =
+ XtVaCreateManagedWidget("devClock", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("chipIdL", labelWidgetClass, box, NULL, 0);
+ if (dev->dev_chipid != -1)
+ XmuSnprintf(buf, sizeof(buf), "0x%x", dev->dev_chipid);
+ else
+ *buf = '\0';
+ node->data->device.chipId =
+ XtVaCreateManagedWidget("chipId", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("chipRevL", labelWidgetClass, box, NULL, 0);
+ if (dev->dev_chiprev != -1)
+ XmuSnprintf(buf, sizeof(buf), "0x%x", dev->dev_chiprev);
+ else
+ *buf = '\0';
+ node->data->device.chipRev =
+ XtVaCreateManagedWidget("chipRev", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("irqL", labelWidgetClass, box, NULL, 0);
+ if (dev->dev_irq != -1)
+ XmuSnprintf(buf, sizeof(buf), "%d", dev->dev_irq);
+ else
+ *buf = '\0';
+ node->data->device.irq =
+ XtVaCreateManagedWidget("irq", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("screenL", labelWidgetClass, box, NULL, 0);
+ if (dev->dev_screen > 0)
+ XmuSnprintf(buf, sizeof(buf), "%d", dev->dev_screen);
+ else
+ *buf = '\0';
+ node->data->device.screen =
+ XtVaCreateManagedWidget("screen", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, NewDeviceCallback, (XtPointer)node);
+ label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ node->data->device.text = label;
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+static void
+NewDeviceCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfDevicePtr dev;
+ Arg args[1];
+ char *label;
+
+ XtSetArg(args[0], XtNstring, &label);
+ XtGetValues(node->data->device.text, args, 1);
+ if (*label == '\0')
+ return;
+
+ parent = node->parent;
+ DeleteNode(node);
+ dev = (XF86ConfDevicePtr)XtCalloc(1, sizeof(XF86ConfDeviceRec));
+ dev->dev_identifier = XtNewString(label);
+ dev->dev_chipid = -1;
+ dev->dev_chiprev = -1;
+ dev->dev_irq = -1;
+
+ XF86Config->conf_device_lst =
+ xf86addDevice(XF86Config->conf_device_lst, dev);
+
+ CreateDevice(parent, dev);
+
+ RelayoutTree();
+}
+
+static void
+DeviceDestroy(TreeNode *node)
+{
+ int i;
+ TreeNode *sc = screenTree;
+
+ for (i = 0; i < computer.num_devices; i++)
+ if ((XF86ConfDevicePtr)(computer.devices[i]->config) ==
+ node->data->device.device) {
+ config = computer.devices[i]->widget;
+ RemoveDeviceCallback(NULL, NULL, NULL);
+ }
+
+ if (sc) {
+ TreeNode *prev;
+
+ sc = prev = sc->child;
+ while (sc->next) {
+ TreeNode *next = sc->next;
+
+ if (sc->data->screen.screen->scrn_monitor ==
+ node->data->monitor.monitor) {
+ XtDestroyWidget(sc->node);
+
+ if (sc->child)
+ DestroyTree(sc->child);
+ if (sc->data)
+ XtFree((XtPointer)sc->data);
+ XtFree((XtPointer)sc);
+
+ if (sc == screenTree->child)
+ sc = prev = next = screenTree->child = next;
+ else
+ prev->next = sc = next;
+ continue;
+ }
+ prev = sc;
+ sc = next;
+ }
+ }
+}
+
+static void
+DeviceUpdate(TreeNode *node)
+{
+ int i;
+ char *str, *tmp;
+
+ /* vendor */
+ XtVaGetValues(node->data->device.vendor, XtNstring, &str, NULL, 0);
+ XtFree(node->data->device.device->dev_vendor);
+ if (*str)
+ node->data->device.device->dev_vendor = XtNewString(str);
+ else
+ node->data->device.device->dev_vendor = NULL;
+
+ /* board */
+ XtVaGetValues(node->data->device.board, XtNstring, &str, NULL, 0);
+ XtFree(node->data->device.device->dev_board);
+ if (*str)
+ node->data->device.device->dev_board = XtNewString(str);
+ else
+ node->data->device.device->dev_board = NULL;
+
+ /* chipset */
+ XtVaGetValues(node->data->device.chipset, XtNstring, &str, NULL, 0);
+ XtFree(node->data->device.device->dev_chipset);
+ if (*str)
+ node->data->device.device->dev_chipset = XtNewString(str);
+ else
+ node->data->device.device->dev_chipset = NULL;
+
+ /* busid */
+ XtVaGetValues(node->data->device.busid, XtNstring, &str, NULL, 0);
+ XtFree(node->data->device.device->dev_busid);
+ if (*str)
+ node->data->device.device->dev_busid = XtNewString(str);
+ else
+ node->data->device.device->dev_busid = NULL;
+
+ /* card */
+ XtVaGetValues(node->data->device.card, XtNstring, &str, NULL, 0);
+ XtFree(node->data->device.device->dev_card);
+ if (*str)
+ node->data->device.device->dev_card = XtNewString(str);
+ else
+ node->data->device.device->dev_card = NULL;
+
+ /* driver */
+ XtVaGetValues(node->data->device.driver, XtNstring, &str, NULL, 0);
+ XtFree(node->data->device.device->dev_driver);
+ if (*str)
+ node->data->device.device->dev_driver = XtNewString(str);
+ else
+ node->data->device.device->dev_driver = NULL;
+
+ /* ramdac */
+ XtVaGetValues(node->data->device.ramdac, XtNstring, &str, NULL, 0);
+ XtFree(node->data->device.device->dev_ramdac);
+ if (*str)
+ node->data->device.device->dev_ramdac = XtNewString(str);
+ else
+ node->data->device.device->dev_ramdac = NULL;
+
+ /* dacSpeed */
+ tmp = NULL;
+ XtVaGetValues(node->data->device.dacSpeed, XtNstring, &str, NULL, 0);
+ for (i = 0; i < CONF_MAXDACSPEEDS && str != tmp; i++) {
+ if ((node->data->device.device->dev_dacSpeeds[i] =
+ (strtod(str, &tmp) * 1000. + .5)) == 0)
+ break;
+ str = tmp;
+ while (isspace(*str))
+ ++str;
+ }
+
+ /* videoRam */
+ XtVaGetValues(node->data->device.videoRam, XtNstring, &str, NULL, 0);
+ node->data->device.device->dev_videoram = strtoul(str, NULL, 0);
+
+ /* textClockFreq */
+ XtVaGetValues(node->data->device.textClockFreq, XtNstring, &str, NULL, 0);
+ node->data->device.device->dev_textclockfreq =
+ strtod(str, NULL) * 1000. + .5;
+
+ /* biosBase */
+ XtVaGetValues(node->data->device.biosBase, XtNstring, &str, NULL, 0);
+ node->data->device.device->dev_bios_base = strtoul(str, NULL, 0);
+
+ /* memBase */
+ XtVaGetValues(node->data->device.memBase, XtNstring, &str, NULL, 0);
+ node->data->device.device->dev_mem_base = strtoul(str, NULL, 0);
+
+ /* ioBase */
+ XtVaGetValues(node->data->device.ioBase, XtNstring, &str, NULL, 0);
+ node->data->device.device->dev_io_base = strtoul(str, NULL, 0);
+
+ /* clockChip */
+ XtVaGetValues(node->data->device.clockChip, XtNstring, &str, NULL, 0);
+ XtFree(node->data->device.device->dev_clockchip);
+ if (*str)
+ node->data->device.device->dev_clockchip = XtNewString(str);
+ else
+ node->data->device.device->dev_clockchip = NULL;
+
+ /* devSpeed */
+ tmp = NULL;
+ XtVaGetValues(node->data->device.devClock, XtNstring, &str, NULL, 0);
+ for (i = 0; i < CONF_MAXCLOCKS && str != tmp; i++) {
+ if ((node->data->device.device->dev_clock[i] =
+ (strtod(str, &tmp) * 1000. + .5)) == 0)
+ break;
+ str = tmp;
+ while (isspace(*str))
+ ++str;
+ }
+ node->data->device.device->dev_clocks = i;
+
+ /* chipId */
+ XtVaGetValues(node->data->device.chipId, XtNstring, &str, NULL, 0);
+ if (*str)
+ node->data->device.device->dev_chipid = strtoul(str, NULL, 0);
+ else
+ node->data->device.device->dev_chipid = -1;
+
+ /* chipRev */
+ XtVaGetValues(node->data->device.chipRev, XtNstring, &str, NULL, 0);
+ if (*str)
+ node->data->device.device->dev_chiprev = strtoul(str, NULL, 0);
+ else
+ node->data->device.device->dev_chiprev = -1;
+
+ /* irq */
+ XtVaGetValues(node->data->device.irq, XtNstring, &str, NULL, 0);
+ if (*str)
+ node->data->device.device->dev_irq = strtoul(str, NULL, 0);
+ else
+ node->data->device.device->dev_irq = -1;
+
+ /* screen */
+ XtVaGetValues(node->data->device.screen, XtNstring, &str, NULL, 0);
+ if (*str)
+ node->data->device.device->dev_screen = strtoul(str, NULL, 0);
+ else
+ node->data->device.device->dev_screen = -1;
+}
+
+/* Screen */
+static void
+CreateScreen(TreeNode *parent, XF86ConfScreenPtr scrn)
+{
+ TreeNode *prev, *node;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (scrn) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->screen.screen = scrn;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = ScreenDestroy;
+ node->update = ScreenUpdate;
+ CreateScreenField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ scrn = (XF86ConfScreenPtr)(scrn->list.next);
+ }
+
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ CreateScreenField(node, True);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+}
+
+static void
+CreateScreenField(TreeNode *node, Bool addnew)
+{
+ Widget box, command, label;
+
+ box = XtVaCreateWidget("screen", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ char buf[256], *str;
+ XF86OptionPtr *options;
+ TreeNode *adaptor, *display;
+ XF86ConfScreenPtr scrn = node->data->screen.screen;
+
+ options = &(scrn->scrn_option_lst);
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ command = XtCreateManagedWidget("options", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
+ label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, scrn->scrn_identifier, NULL, 0);
+
+ XtCreateManagedWidget("defaultDepthL", labelWidgetClass, box, NULL, 0);
+ if (scrn->scrn_defaultdepth)
+ XmuSnprintf(buf, sizeof(buf), "%d", scrn->scrn_defaultdepth);
+ else
+ *buf = '\0';
+ node->data->screen.defaultDepth =
+ XtVaCreateManagedWidget("defaultDepth", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("defaultBppL", labelWidgetClass, box, NULL, 0);
+ if (scrn->scrn_defaultbpp)
+ XmuSnprintf(buf, sizeof(buf), "%d", scrn->scrn_defaultbpp);
+ else
+ *buf = '\0';
+ node->data->screen.defaultBpp =
+ XtVaCreateManagedWidget("defaultBpp", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("defaultFbBppL", labelWidgetClass, box, NULL, 0);
+ if (scrn->scrn_defaultfbbpp)
+ XmuSnprintf(buf, sizeof(buf), "%d", scrn->scrn_defaultfbbpp);
+ else
+ *buf = '\0';
+ node->data->screen.defaultFbBpp =
+ XtVaCreateManagedWidget("defaultFbBpp", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("monitorL", labelWidgetClass, box, NULL, 0);
+ str = scrn->scrn_monitor_str ? scrn->scrn_monitor_str : "";
+ node->data->screen.monitor =
+ XtVaCreateManagedWidget("monitor", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("deviceL", labelWidgetClass, box, NULL, 0);
+ str = scrn->scrn_device_str ? scrn->scrn_device_str : "";
+ node->data->screen.device =
+ XtVaCreateManagedWidget("device", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str,
+ NULL, 0);
+
+ command = XtVaCreateManagedWidget("videoAdaptor", toggleWidgetClass,
+ tree, XtNstate, True,
+ XtNtreeParent, box, NULL, 0);
+ adaptor = NewNode(node, command, command, node->node, NULL);
+ CreateScreenAdaptor(adaptor, scrn->scrn_adaptor_lst);
+ node->child = adaptor;
+
+ command = XtVaCreateManagedWidget("Display", toggleWidgetClass,
+ tree, XtNstate, True,
+ XtNtreeParent, box, NULL, 0);
+ display = NewNode(node, command, command, node->node, NULL);
+ CreateScreenDisplay(display, scrn->scrn_display_lst);
+ adaptor->next = display;
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, NewScreenCallback, (XtPointer)node);
+ label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ node->data->screen.text = label;
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+static void
+NewScreenCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfScreenPtr scrn;
+ Arg args[1];
+ char *label;
+
+ XtSetArg(args[0], XtNstring, &label);
+ XtGetValues(node->data->screen.text, args, 1);
+ if (*label == '\0')
+ return;
+
+ parent = node->parent;
+ DeleteNode(node);
+ scrn = (XF86ConfScreenPtr)XtCalloc(1, sizeof(XF86ConfScreenRec));
+ scrn->scrn_identifier = XtNewString(label);
+ XF86Config->conf_screen_lst =
+ xf86addScreen(XF86Config->conf_screen_lst, scrn);
+
+ {
+ TreeNode *lay = layoutTree->child;
+ Widget sme;
+
+ /* last one is the "new" entry */
+ while (lay && lay->next != NULL) {
+ /* Adjacency is the first entry */
+ TreeNode *adj = lay->child->child;
+
+ while (adj != NULL) {
+ sme = XtCreateManagedWidget(label, smeBSBObjectClass,
+ adj->data->adjacency.menu, NULL, 0);
+ XtAddCallback(sme, XtNcallback, adj->next != NULL ?
+ AdjacencyMenuCallback : NewAdjacencyCallback,
+ (XtPointer)adj);
+ adj = adj->next;
+ }
+ lay = lay->next;
+ }
+ }
+
+ CreateScreen(parent, scrn);
+
+ RelayoutTree();
+}
+
+static void
+ScreenDestroy(TreeNode *node)
+{
+ if (node->data->screen.screen) {
+ int i;
+ TreeNode *lay = layoutTree->child;
+
+ /* last one is the "new" entry */
+ while (lay && lay->next) {
+ /* Adjacency is the first entry */
+ TreeNode *adj = lay->child->child;
+ CompositeWidget composite;
+
+ while (adj) {
+ TreeNode *next = adj->next;
+
+ composite = (CompositeWidget)adj->data->adjacency.menu;
+
+ for (i = 0; i < composite->composite.num_children; ++i)
+ if (strcmp(XtName(composite->composite.children[i]),
+ node->data->screen.screen->scrn_identifier) == 0) {
+ XtDestroyWidget(composite->composite.children[i]);
+ break;
+ }
+
+ if (adj->data->adjacency.screen == node->data->screen.screen)
+ DeleteNode(adj);
+
+ adj = next;
+ }
+
+ lay = lay->next;
+ }
+
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->screen == node->data->screen.screen) {
+ config = computer.screens[i]->widget;
+ RemoveDeviceCallback(NULL, NULL, NULL);
+ }
+
+ /* for the case of screens added and removed in the expert dialog */
+ xf86removeScreen(XF86Config, node->data->screen.screen);
+ }
+}
+
+static void
+ScreenUpdate(TreeNode *node)
+{
+ char *str;
+
+ /* defautDepth */
+ XtVaGetValues(node->data->screen.defaultDepth, XtNstring, &str, NULL, 0);
+ node->data->screen.screen->scrn_defaultdepth = strtoul(str, NULL, 0);
+
+ /* defautBpp */
+ XtVaGetValues(node->data->screen.defaultBpp, XtNstring, &str, NULL, 0);
+ node->data->screen.screen->scrn_defaultbpp = strtoul(str, NULL, 0);
+
+ /* defautFbBpp */
+ XtVaGetValues(node->data->screen.defaultFbBpp, XtNstring, &str, NULL, 0);
+ node->data->screen.screen->scrn_defaultfbbpp = strtoul(str, NULL, 0);
+
+
+ /* XXX Monitor and Device should be changed to a menu interface */
+ /* monitor */
+ XtVaGetValues(node->data->screen.monitor, XtNstring, &str, NULL, 0);
+ XtFree(node->data->screen.screen->scrn_monitor_str);
+ if (*str)
+ node->data->screen.screen->scrn_monitor_str = XtNewString(str);
+ else
+ node->data->screen.screen->scrn_monitor_str = NULL;
+
+ /* XXX Monitor and Device should be changed to a menu interface */
+ /* device */
+ XtVaGetValues(node->data->screen.device, XtNstring, &str, NULL, 0);
+ XtFree(node->data->screen.screen->scrn_device_str);
+ if (*str)
+ node->data->screen.screen->scrn_device_str = XtNewString(str);
+ else
+ node->data->screen.screen->scrn_device_str = NULL;
+}
+
+static void
+CreateScreenAdaptor(TreeNode *parent, XF86ConfAdaptorLinkPtr lnk)
+{
+ TreeNode *node, *prev;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (lnk) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->adaptorlink.adaptorlink = lnk;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = ScreenAdaptorDestroy;
+ CreateScreenAdaptorField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ lnk = (XF86ConfAdaptorLinkPtr)(lnk->list.next);
+ }
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ CreateScreenAdaptorField(node, True);
+}
+
+static void
+CreateScreenAdaptorField(TreeNode *node, Bool addnew)
+{
+ Widget box, command, label;
+
+ box = XtVaCreateWidget("adaptor", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ XF86ConfAdaptorLinkPtr lnk = node->data->adaptorlink.adaptorlink;
+
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, lnk->al_adaptor_str, NULL, 0);
+ }
+ else {
+ Widget sme;
+ XF86ConfVideoAdaptorPtr ptr = XF86Config->conf_videoadaptor_lst;
+
+ command = XtVaCreateManagedWidget("new", menuButtonWidgetClass, box,
+ XtNmenuName, "adaptorMenu", NULL, 0);
+ node->data->adaptorlink.menu =
+ XtVaCreatePopupShell("adaptorMenu", simpleMenuWidgetClass, box,
+ XtNleftMargin, 1, XtNrightMargin, 1,
+ XtNtopMargin, 1, XtNbottomMargin, 1,
+ NULL, 0);
+ while (ptr) {
+ sme = XtCreateManagedWidget(ptr->va_identifier, smeBSBObjectClass,
+ node->data->adaptorlink.menu, NULL, 0);
+ XtAddCallback(sme, XtNcallback, NewScreenAdaptorCallback,
+ (XtPointer)node);
+ ptr = (XF86ConfVideoAdaptorPtr)(ptr->list.next);
+ }
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+/*ARGSUSED*/
+static void
+NewScreenAdaptorCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfAdaptorLinkPtr link;
+ char *ident = XtName(w);
+
+ parent = node->parent;
+ DeleteNode(node);
+ link = (XF86ConfAdaptorLinkPtr)XtCalloc(1, sizeof(XF86ConfAdaptorLinkRec));
+ link->al_adaptor_str = XtNewString(ident);
+ parent->parent->data->screen.screen->scrn_adaptor_lst =
+ xf86addScreenAdaptor(parent->parent->data->screen.screen->scrn_adaptor_lst,
+ link);
+
+ CreateScreenAdaptor(parent, link);
+ RelayoutTree();
+}
+
+/*ARGUSED*/
+static void
+ScreenAdaptorDestroy(TreeNode *node)
+{
+ if (node->data->adaptorlink.adaptorlink)
+ xf86removeScreenAdaptorLink(node->parent->parent->data->screen.screen,
+ node->data->adaptorlink.adaptorlink);
+}
+
+static void
+CreateScreenDisplay(TreeNode *parent, XF86ConfDisplayPtr dsp)
+{
+ TreeNode *node, *prev;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (dsp) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->display.display = dsp;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = ScreenDisplayDestroy;
+ node->update = ScreenDisplayUpdate;
+ CreateScreenDisplayField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ dsp = (XF86ConfDisplayPtr)(dsp->list.next);
+ }
+ node = NewNode(parent, NULL, NULL, parent->node, NULL);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ CreateScreenDisplayField(node, True);
+}
+
+static void
+CreateScreenDisplayField(TreeNode *node, Bool addnew)
+{
+ Widget box, command;
+
+ box = XtVaCreateWidget("display", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ char *str, buf[256];
+ XF86OptionPtr *options;
+ XF86ConfDisplayPtr dsp = node->data->display.display;
+ TreeNode *modes;
+
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ options = &(dsp->disp_option_lst);
+ command = XtCreateManagedWidget("options", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
+
+ XtCreateManagedWidget("viewportL", labelWidgetClass, box, NULL, 0);
+ if (dsp->disp_frameX0 != 0 || dsp->disp_frameY0 != 0)
+ XmuSnprintf(buf, sizeof(buf), "%d %d", dsp->disp_frameX0, dsp->disp_frameY0);
+ else
+ *buf = '\0';
+ node->data->display.viewport =
+ XtVaCreateManagedWidget("viewport", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf, NULL, 0);
+
+ XtCreateManagedWidget("virtualL", labelWidgetClass, box, NULL, 0);
+ if (dsp->disp_virtualX != 0 || dsp->disp_virtualY != 0)
+ XmuSnprintf(buf, sizeof(buf), "%d %d", dsp->disp_virtualX, dsp->disp_virtualY);
+ else
+ *buf = '\0';
+ node->data->display.c_virtual =
+ XtVaCreateManagedWidget("virtual", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf, NULL, 0);
+
+ XtCreateManagedWidget("depthL", labelWidgetClass, box, NULL, 0);
+ if (dsp->disp_depth != 0)
+ XmuSnprintf(buf, sizeof(buf), "%d", dsp->disp_depth);
+ else
+ *buf = '\0';
+ node->data->display.depth =
+ XtVaCreateManagedWidget("depth", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf, NULL, 0);
+
+ XtCreateManagedWidget("bppL", labelWidgetClass, box, NULL, 0);
+ if (dsp->disp_bpp != 0)
+ XmuSnprintf(buf, sizeof(buf), "%d", dsp->disp_bpp);
+ else
+ *buf = '\0';
+ node->data->display.bpp =
+ XtVaCreateManagedWidget("bpp", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf, NULL, 0);
+
+ XtCreateManagedWidget("visualL", labelWidgetClass, box, NULL, 0);
+ str = dsp->disp_visual != NULL ? dsp->disp_visual : "";
+ node->data->display.visual =
+ XtVaCreateManagedWidget("visual", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str, NULL, 0);
+
+ XtCreateManagedWidget("weightL", labelWidgetClass, box, NULL, 0);
+ if (dsp->disp_weight.red > 0)
+ XmuSnprintf(buf, sizeof(buf), "%d %d %d",
+ dsp->disp_weight.red, dsp->disp_weight.green, dsp->disp_weight.blue);
+ else
+ *buf = '\0';
+ node->data->display.weight =
+ XtVaCreateManagedWidget("weight", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf, NULL, 0);
+
+ XtCreateManagedWidget("blackL", labelWidgetClass, box, NULL, 0);
+ if (dsp->disp_black.red >= 0)
+ XmuSnprintf(buf, sizeof(buf), "0x%04x 0x%04x 0x%04x",
+ dsp->disp_black.red, dsp->disp_black.green, dsp->disp_black.blue);
+ else
+ *buf = '\0';
+ node->data->display.black =
+ XtVaCreateManagedWidget("black", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf, NULL, 0);
+
+ XtCreateManagedWidget("whiteL", labelWidgetClass, box, NULL, 0);
+ if (dsp->disp_white.red >= 0)
+ XmuSnprintf(buf, sizeof(buf), "0x%04x 0x%04x 0x%04x",
+ dsp->disp_white.red, dsp->disp_white.green, dsp->disp_white.blue);
+ else
+ *buf = '\0';
+ node->data->display.white =
+ XtVaCreateManagedWidget("white", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf, NULL, 0);
+
+ command = XtVaCreateManagedWidget("Modes", toggleWidgetClass, tree,
+ XtNstate, True, XtNtreeParent, box,
+ NULL, 0);
+ modes = NewNode(node, command, command, node->node, NULL);
+ node->child = modes;
+ CreateDisplayMode(modes, dsp->disp_mode_lst);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box, NULL, 0);
+ XtAddCallback(command, XtNcallback, NewScreenDisplayCallback,
+ (XtPointer)node);
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+/*ARGSUSED*/
+static void
+NewScreenDisplayCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfDisplayPtr dsp;
+
+ parent = node->parent;
+ DeleteNode(node);
+ dsp = (XF86ConfDisplayPtr)XtCalloc(1, sizeof(XF86ConfDisplayRec));
+ dsp->disp_black.red = dsp->disp_black.green = dsp->disp_black.blue =
+ dsp->disp_white.red = dsp->disp_white.green = dsp->disp_white.blue = -1;
+ parent->parent->data->screen.screen->scrn_display_lst =
+ xf86addScreenDisplay(parent->parent->data->screen.screen->scrn_display_lst,
+ dsp);
+
+ CreateScreenDisplay(parent, dsp);
+ RelayoutTree();
+}
+
+static void
+ScreenDisplayDestroy(TreeNode *node)
+{
+ if (node->data->display.display)
+ xf86removeScreenDisplay(node->parent->parent->data->screen.screen,
+ node->data->display.display);
+}
+
+static void
+ScreenDisplayUpdate(TreeNode *node)
+{
+ char *str, *tmp;
+ int x, y;
+
+ /* viewport */
+ XtVaGetValues(node->data->display.viewport, XtNstring, &str, NULL, 0);
+ if (sscanf(str, "%d %d", &x, &y) == 2) {
+ node->data->display.display->disp_frameX0 = x;
+ node->data->display.display->disp_frameY0 = y;
+ }
+
+ /* virtual */
+ XtVaGetValues(node->data->display.c_virtual, XtNstring, &str, NULL, 0);
+ if (sscanf(str, "%d %d", &x, &y) == 2) {
+ node->data->display.display->disp_virtualX = x;
+ node->data->display.display->disp_virtualY = y;
+ }
+
+ /* depth */
+ XtVaGetValues(node->data->display.depth, XtNstring, &str, NULL, 0);
+ node->data->display.display->disp_depth = strtoul(str, NULL, 0);
+
+ /* bpp */
+ XtVaGetValues(node->data->display.bpp, XtNstring, &str, NULL, 0);
+ node->data->display.display->disp_bpp = strtoul(str, NULL, 0);
+
+ /* visual */
+ XtVaGetValues(node->data->display.visual, XtNstring, &str, NULL, 0);
+ XtFree(node->data->display.display->disp_visual);
+ if (*str)
+ node->data->display.display->disp_visual = XtNewString(str);
+ else
+ node->data->display.display->disp_visual = NULL;
+
+ /* weight */
+ XtVaGetValues(node->data->display.weight, XtNstring, &str, NULL, 0);
+ node->data->display.display->disp_weight.red = strtoul(str, &tmp, 0);
+ if (str == tmp)
+ node->data->display.display->disp_weight.red = 0;
+ else {
+ str = tmp;
+ while (isspace(*str))
+ ++str;
+ node->data->display.display->disp_weight.green = strtoul(str, &tmp, 0);
+ if (str != tmp) {
+ str = tmp;
+ while (isspace(*str))
+ ++str;
+ node->data->display.display->disp_weight.blue = strtoul(str, &tmp, 0);
+ }
+ }
+
+ /* black */
+ XtVaGetValues(node->data->display.black, XtNstring, &str, NULL, 0);
+ node->data->display.display->disp_black.red = strtoul(str, &tmp, 0);
+ if (str == tmp)
+ node->data->display.display->disp_black.red = -1;
+ else {
+ str = tmp;
+ while (isspace(*str))
+ ++str;
+ node->data->display.display->disp_black.green = strtoul(str, &tmp, 0);
+ if (str != tmp) {
+ str = tmp;
+ while (isspace(*str))
+ ++str;
+ node->data->display.display->disp_black.blue = strtoul(str, &tmp, 0);
+ }
+ }
+
+ /* white */
+ XtVaGetValues(node->data->display.white, XtNstring, &str, NULL, 0);
+ node->data->display.display->disp_white.red = strtoul(str, &tmp, 0);
+ if (str == tmp)
+ node->data->display.display->disp_white.red = -1;
+ else {
+ str = tmp;
+ while (isspace(*str))
+ ++str;
+ node->data->display.display->disp_white.green = strtoul(str, &tmp, 0);
+ if (str != tmp) {
+ str = tmp;
+ while (isspace(*str))
+ ++str;
+ node->data->display.display->disp_white.blue = strtoul(str, &tmp, 0);
+ }
+ }
+}
+
+static void
+CreateDisplayMode(TreeNode *parent, XF86ModePtr modes)
+{
+ TreeNode *node, *prev;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (modes) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->mode.mode = modes;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = DisplayModeDestroy;
+ CreateDisplayModeField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ modes = (XF86ModePtr)(modes->list.next);
+ }
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ CreateDisplayModeField(node, True);
+}
+
+static void
+CreateDisplayModeField(TreeNode *node, Bool addnew)
+{
+ Widget box, command, text;
+
+ box = XtVaCreateWidget("mode", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+ if (!addnew) {
+ XF86ModePtr mode = node->data->mode.mode;
+
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback,
+ (XtPointer)node);
+ text = XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, mode->mode_name, NULL, 0);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box, NULL, 0);
+ XtAddCallback(command, XtNcallback, NewDisplayModeCallback,
+ (XtPointer)node);
+ text = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit, NULL, 0);
+ }
+ node->data->mode.text = text;
+ if (node->treeParent && XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+/*ARGSUSED*/
+static void
+NewDisplayModeCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ModePtr mode;
+ Arg args[1];
+ char *ident;
+
+ XtSetArg(args[0], XtNstring, &ident);
+ XtGetValues(node->data->mode.text, args, 1);
+ if (*ident == '\0')
+ return;
+
+ parent = node->parent;
+ DeleteNode(node);
+ mode = (XF86ModePtr)XtCalloc(1, sizeof(XF86ModeRec));
+ mode->mode_name = XtNewString(ident);
+ parent->parent->data->display.display->disp_mode_lst =
+ xf86addDisplayMode(parent->parent->data->display.display->disp_mode_lst,
+ mode);
+
+ CreateDisplayMode(parent, mode);
+ RelayoutTree();
+}
+
+/*ARGUSED*/
+static void
+DisplayModeDestroy(TreeNode *node)
+{
+ if (node->data->mode.mode)
+ xf86removeDisplayMode(node->parent->parent->data->display.display,
+ node->data->mode.mode);
+}
+
+/* Input */
+static void
+CreateInput(TreeNode *parent, XF86ConfInputPtr input)
+{
+ TreeNode *prev, *node;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (input) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->input.input = input;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = InputDestroy;
+ node->update = InputUpdate;
+ CreateInputField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ input = (XF86ConfInputPtr)(input->list.next);
+ }
+
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ CreateInputField(node, True);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+}
+
+static void
+CreateInputField(TreeNode *node, Bool addnew)
+{
+ Widget box, command;
+
+ box = XtVaCreateWidget("input", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ char *str;
+ XF86OptionPtr *options;
+ XF86ConfInputPtr inp = node->data->input.input;
+
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ options = &(inp->inp_option_lst);
+ command = XtCreateManagedWidget("options", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
+ XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, inp->inp_identifier, NULL, 0);
+
+ XtCreateManagedWidget("driverL", labelWidgetClass, box, NULL, 0);
+ str = inp->inp_driver != NULL ? inp->inp_driver : "";
+ node->data->input.text =
+ XtVaCreateManagedWidget("driver", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, str, NULL, 0);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box, NULL, 0);
+ XtAddCallback(command, XtNcallback, NewInputCallback,
+ (XtPointer)node);
+ node->data->input.text =
+ XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit, NULL, 0);
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+/*ARGSUSED*/
+static void
+NewInputCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfInputPtr input;
+ Arg args[1];
+ char *ident;
+
+ XtSetArg(args[0], XtNstring, &ident);
+ XtGetValues(node->data->input.text, args, 1);
+ if (*ident == '\0')
+ return;
+
+ parent = node->parent;
+ DeleteNode(node);
+ input = (XF86ConfInputPtr)XtCalloc(1, sizeof(XF86ConfInputRec));
+ input->inp_identifier = XtNewString(ident);
+ XF86Config->conf_input_lst =
+ xf86addInput(XF86Config->conf_input_lst, input);
+
+ {
+ TreeNode *lay = layoutTree->child;
+ Widget sme;
+
+ /* last one is the "new" entry */
+ while (lay && lay->next != NULL) {
+ /* Inputref is the second entry */
+ TreeNode *iref = lay->child->next->child;
+
+ while (iref && iref->next)
+ iref = iref->next;
+ sme = XtCreateManagedWidget(ident, smeBSBObjectClass,
+ iref->data->inputref.menu, NULL, 0);
+ XtAddCallback(sme, XtNcallback, NewInputrefCallback,
+ (XtPointer)iref);
+ lay = lay->next;
+ }
+ }
+
+ CreateInput(parent, input);
+ RelayoutTree();
+}
+
+/*ARGUSED*/
+static void
+InputDestroy(TreeNode *node)
+{
+ if (node->data->input.input) {
+ int i;
+ TreeNode *lay = layoutTree->child;
+
+ /* last one is the "new" entry */
+ while (lay && lay->next) {
+ /* Inputref is the second entry */
+ TreeNode *iref = lay->child->next->child;
+ CompositeWidget composite;
+
+ while (iref && iref->next) {
+ TreeNode *next = iref->next;
+
+ if (iref && strcmp(iref->data->inputref.inputref->iref_inputdev_str,
+ node->data->input.input->inp_identifier) == 0)
+ DeleteNode(iref);
+ iref = next;
+ }
+
+ composite = (CompositeWidget)iref->data->inputref.menu;
+
+ for (i = 0; i < composite->composite.num_children; ++i)
+ if (strcmp(XtName(composite->composite.children[i]),
+ node->data->input.input->inp_identifier) == 0)
+ XtDestroyWidget(composite->composite.children[i]);
+
+ lay = lay->next;
+ }
+
+ for (i = 0; i < computer.num_devices; i++)
+ if ((XF86ConfInputPtr)(computer.devices[i]->config) ==
+ node->data->input.input) {
+ config = computer.devices[i]->widget;
+ RemoveDeviceCallback(NULL, NULL, NULL);
+ }
+ }
+}
+
+static void
+InputUpdate(TreeNode *node)
+{
+ char *str;
+
+ /* vendor */
+ XtVaGetValues(node->data->input.text, XtNstring, &str, NULL, 0);
+ XtFree(node->data->input.input->inp_driver);
+ if (*str)
+ node->data->input.input->inp_driver = XtNewString(str);
+ else
+ node->data->input.input->inp_driver = NULL;
+}
+
+/* Layout */
+static void
+CreateLayout(TreeNode *parent, XF86ConfLayoutPtr lay)
+{
+ TreeNode *prev, *node;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (lay) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->layout.layout = lay;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = LayoutDestroy;
+ CreateLayoutField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ lay = (XF86ConfLayoutPtr)(lay->list.next);
+ }
+
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ CreateLayoutField(node, True);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+}
+
+static void
+CreateLayoutField(TreeNode *node, Bool addnew)
+{
+ Widget box, command, label;
+
+ box = XtVaCreateWidget("layout", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ TreeNode *adjacency, *inputref;
+ XF86OptionPtr *options;
+ XF86ConfLayoutPtr lay = node->data->layout.layout;
+
+ options = &(lay->lay_option_lst);
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ command = XtCreateManagedWidget("options", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
+ label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, lay->lay_identifier, NULL, 0);
+
+ command = XtVaCreateManagedWidget("Adjacency", toggleWidgetClass, tree,
+ XtNstate, True, XtNtreeParent, box,
+ NULL, 0);
+ adjacency = NewNode(node, command, command, box, NULL);
+ node->child = adjacency;
+ CreateAdjacency(adjacency, lay->lay_adjacency_lst);
+
+ command = XtVaCreateManagedWidget("Inputref", toggleWidgetClass, tree,
+ XtNstate, True, XtNtreeParent, box,
+ NULL, 0);
+ inputref = NewNode(node, command, command, box, NULL);
+ adjacency->next = inputref;
+ CreateInputref(inputref, lay->lay_input_lst);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, NewLayoutCallback, (XtPointer)node);
+ label = XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ node->data->layout.text = label;
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+/*ARGUSED*/
+static void
+LayoutDestroy(TreeNode *node)
+{
+ if (node->data->layout.layout)
+ xf86removeLayout(XF86Config, node->data->layout.layout);
+}
+
+/*ARGSUSED*/
+static void
+NewLayoutCallback(Widget unused, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfLayoutPtr lay;
+ Arg args[1];
+ char *label;
+
+ XtSetArg(args[0], XtNstring, &label);
+ XtGetValues(node->data->layout.text, args, 1);
+ if (*label == '\0')
+ return;
+
+ parent = node->parent;
+ DeleteNode(node);
+ lay = (XF86ConfLayoutPtr)XtCalloc(1, sizeof(XF86ConfLayoutRec));
+ lay->lay_identifier = XtNewString(label);
+ XF86Config->conf_layout_lst = xf86addLayout(XF86Config->conf_layout_lst, lay);
+
+ CreateLayout(parent, lay);
+ RelayoutTree();
+}
+
+static void
+CreateAdjacency(TreeNode *parent, XF86ConfAdjacencyPtr adj)
+{
+ TreeNode *prev, *node;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (adj) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->adjacency.screen = adj ? adj->adj_screen : NULL;
+ data->adjacency.adjacency = adj;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = AdjacencyDestroy;
+ CreateAdjacencyField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ adj = (XF86ConfAdjacencyPtr)(adj->list.next);
+ }
+
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ CreateAdjacencyField(node, True);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+}
+
+static void
+CreateAdjacencyField(TreeNode *node, Bool addnew)
+{
+ Widget box, command, label, sme;
+ XF86ConfScreenPtr ptr = XF86Config->conf_screen_lst;
+
+ box = XtVaCreateWidget("adjacency", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ node->data->adjacency.menu =
+ XtVaCreatePopupShell("screenMenu", simpleMenuWidgetClass, box,
+ XtNleftMargin, 1, XtNrightMargin, 1,
+ XtNtopMargin, 1, XtNbottomMargin, 1,
+ NULL, 0);
+ while (ptr) {
+ sme = XtCreateManagedWidget(ptr->scrn_identifier, smeBSBObjectClass,
+ node->data->adjacency.menu, NULL, 0);
+ XtAddCallback(sme, XtNcallback, !addnew ?
+ AdjacencyMenuCallback : NewAdjacencyCallback,
+ (XtPointer)node);
+ ptr = (XF86ConfScreenPtr)(ptr->list.next);
+ }
+
+ if (!addnew) {
+ char buf[32];
+ Cardinal width, height;
+ Widget left, right, above, below, relative, absolute;
+ XF86ConfAdjacencyPtr adj = node->data->adjacency.adjacency;
+
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ label = XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, adj->adj_screen->scrn_identifier,
+ NULL, 0);
+
+ XtCreateManagedWidget("scrnumL", labelWidgetClass, box, NULL, 0);
+ if (adj->adj_scrnum >= 0)
+ XmuSnprintf(buf, sizeof(buf), "%d", adj->adj_scrnum);
+ else
+ *buf = 0;
+ node->data->adjacency.scrnum =
+ XtVaCreateManagedWidget("scrnum", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf, NULL, 0);
+ above = XtVaCreateManagedWidget("above", toggleWidgetClass, box,
+ XtNstate, adj->adj_where == CONF_ADJ_ABOVE ?
+ True : False, NULL, 0);
+ XtAddCallback(above, XtNcallback, AdjacencyToggleCallback, (XtPointer)node);
+ left = XtVaCreateManagedWidget("leftOf", toggleWidgetClass, box,
+ XtNradioGroup, above,
+ XtNstate, adj->adj_where == CONF_ADJ_LEFTOF ?
+ True : False, NULL, 0);
+ XtAddCallback(left, XtNcallback, AdjacencyToggleCallback, (XtPointer)node);
+
+ node->data->adjacency.button =
+ XtVaCreateManagedWidget("screen", menuButtonWidgetClass, box,
+ XtNmenuName, "screenMenu", NULL, 0);
+
+ right = XtVaCreateManagedWidget("rightOf", toggleWidgetClass, box,
+ XtNradioGroup, left,
+ XtNstate, adj->adj_where == CONF_ADJ_RIGHTOF ?
+ True : False, NULL, 0);
+ XtAddCallback(right, XtNcallback, AdjacencyToggleCallback, (XtPointer)node);
+ below = XtVaCreateManagedWidget("below", toggleWidgetClass, box,
+ XtNradioGroup, right,
+ XtNstate, adj->adj_where == CONF_ADJ_BELOW ?
+ True : False, NULL, 0);
+ XtAddCallback(below, XtNcallback, AdjacencyToggleCallback, (XtPointer)node);
+ relative = XtVaCreateManagedWidget("relative", toggleWidgetClass, box,
+ XtNradioGroup, below,
+ XtNstate, adj->adj_where == CONF_ADJ_RELATIVE ?
+ True : False, NULL, 0);
+ XtAddCallback(relative, XtNcallback, AdjacencyToggleCallback, (XtPointer)node);
+ absolute = XtVaCreateManagedWidget("absolute", toggleWidgetClass, box,
+ XtNradioGroup, relative,
+ XtNstate, adj->adj_where == CONF_ADJ_ABSOLUTE ?
+ True : False, NULL, 0);
+ XtAddCallback(absolute, XtNcallback, AdjacencyToggleCallback, (XtPointer)node);
+
+ XtCreateManagedWidget("adjxL", labelWidgetClass, box, NULL, 0);
+ XmuSnprintf(buf, sizeof(buf), "%d", adj->adj_x);
+ node->data->adjacency.adjx =
+ XtVaCreateManagedWidget("adjx", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf, NULL, 0);
+
+ XtCreateManagedWidget("adjyL", labelWidgetClass, box, NULL, 0);
+ XmuSnprintf(buf, sizeof(buf), "%d", adj->adj_y);
+ node->data->adjacency.adjy =
+ XtVaCreateManagedWidget("adjy", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit,
+ XtNstring, buf, NULL, 0);
+
+ XtVaGetValues(node->data->adjacency.button, XtNwidth, &width,
+ XtNheight, &height, NULL, 0);
+ if (adj->adj_where > CONF_ADJ_ABSOLUTE &&
+ adj->adj_where <= CONF_ADJ_RELATIVE)
+ XtVaSetValues(node->data->adjacency.button, XtNlabel,
+ adj->adj_refscreen, XtNwidth, width,
+ XtNheight, height, NULL, 0);
+ else
+ XtVaSetValues(node->data->adjacency.button, XtNlabel, "",
+ XtNwidth, width, XtNheight, height, NULL, 0);
+ }
+ else
+ XtVaCreateManagedWidget("new", menuButtonWidgetClass, box,
+ XtNmenuName, "screenMenu", NULL, 0);
+
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+static void
+AdjacencyDestroy(TreeNode *node)
+{
+ if (node->data->adjacency.adjacency)
+ xf86removeAdjacency(node->parent->parent->data->layout.layout,
+ node->data->adjacency.adjacency);
+}
+
+/*ARGSUSED*/
+static void
+NewAdjacencyCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfAdjacencyPtr adj;
+ char *ident = XtName(w);
+
+ parent = node->parent;
+ DeleteNode(node);
+ adj = (XF86ConfAdjacencyPtr)XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
+ adj->adj_screen = xf86findScreen(ident, XF86Config->conf_screen_lst);
+ if (adj->adj_screen)
+ adj->adj_screen_str = XtNewString(adj->adj_screen->scrn_identifier);
+ parent->parent->data->layout.layout->lay_adjacency_lst =
+ xf86addAdjacency(parent->parent->data->layout.layout->lay_adjacency_lst,
+ adj);
+
+ CreateAdjacency(parent, adj);
+ RelayoutTree();
+}
+
+/*ARGUSED*/
+static void
+AdjacencyMenuCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *node = (TreeNode*)user_data;
+ XF86ConfAdjacencyPtr adj = node->data->adjacency.adjacency;
+
+ XtFree(adj->adj_refscreen);
+ adj->adj_refscreen = XtNewString(XtName(w));
+ XtVaSetValues(node->data->adjacency.button, XtNlabel, XtName(w), NULL, 0);
+}
+
+static void
+AdjacencyToggleCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *node = (TreeNode*)user_data;
+ XF86ConfAdjacencyPtr adj = node->data->adjacency.adjacency;
+ char *x, *y;
+
+ if ((Bool)(long)call_data == False)
+ return;
+
+ XtVaGetValues(node->data->adjacency.adjx, XtNstring, &x, NULL, 0);
+ XtVaGetValues(node->data->adjacency.adjy, XtNstring, &y, NULL, 0);
+
+ adj->adj_x = strtol(x, NULL, 0);
+ adj->adj_y = strtol(y, NULL, 0);
+
+ if (strcmp(XtName(w), "absolute") == 0) {
+ XtVaSetValues(node->data->adjacency.button, XtNlabel, "", NULL, 0);
+ adj->adj_where = CONF_ADJ_ABSOLUTE;
+ return;
+ }
+ if (strcmp(XtName(w), "relative") == 0)
+ adj->adj_where = CONF_ADJ_RELATIVE;
+ else if (strcmp(XtName(w), "leftOf") == 0)
+ adj->adj_where = CONF_ADJ_LEFTOF;
+ else if (strcmp(XtName(w), "rightOf") == 0)
+ adj->adj_where = CONF_ADJ_RIGHTOF;
+ else if (strcmp(XtName(w), "above") == 0)
+ adj->adj_where = CONF_ADJ_ABOVE;
+ else if (strcmp(XtName(w), "below") == 0)
+ adj->adj_where = CONF_ADJ_BELOW;
+}
+
+/* Inputref */
+static void
+CreateInputref(TreeNode *parent, XF86ConfInputrefPtr input)
+{
+ TreeNode *prev, *node;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (input) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->inputref.inputref = input;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = InputrefDestroy;
+ CreateInputrefField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ input = (XF86ConfInputrefPtr)(input->list.next);
+ }
+
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ CreateInputrefField(node, True);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+}
+
+static void
+CreateInputrefField(TreeNode *node, Bool addnew)
+{
+ Widget box, command;
+
+ box = XtVaCreateWidget("inputref", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ XF86OptionPtr *options;
+ XF86ConfInputrefPtr inp = node->data->inputref.inputref;
+
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ options = &(inp->iref_option_lst);
+ command = XtCreateManagedWidget("options", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
+ XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, inp->iref_inputdev_str, NULL, 0);
+ }
+ else {
+ Widget sme;
+ XF86ConfInputPtr ptr = XF86Config->conf_input_lst;
+
+ XtVaCreateManagedWidget("new", menuButtonWidgetClass, box,
+ XtNmenuName, "inputMenu", NULL, 0);
+ node->data->inputref.menu =
+ XtVaCreatePopupShell("inputMenu", simpleMenuWidgetClass, box,
+ XtNleftMargin, 1, XtNrightMargin, 1,
+ XtNtopMargin, 1, XtNbottomMargin, 1,
+ NULL, 0);
+
+ while (ptr) {
+ sme = XtCreateManagedWidget(ptr->inp_identifier, smeBSBObjectClass,
+ node->data->inputref.menu, NULL, 0);
+ XtAddCallback(sme, XtNcallback, NewInputrefCallback,
+ (XtPointer)node);
+ ptr = (XF86ConfInputPtr)(ptr->list.next);
+ }
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+/*ARGSUSED*/
+static void
+NewInputrefCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfInputrefPtr input;
+ char *ident = XtName(w);
+
+ parent = node->parent;
+ DeleteNode(node);
+ input = (XF86ConfInputrefPtr)XtCalloc(1, sizeof(XF86ConfInputrefRec));
+ input->iref_inputdev_str = XtNewString(ident);
+ parent->parent->data->layout.layout->lay_input_lst =
+ xf86addInputref(parent->parent->data->layout.layout->lay_input_lst, input);
+
+ CreateInputref(parent, input);
+ RelayoutTree();
+}
+
+/*ARGUSED*/
+static void
+InputrefDestroy(TreeNode *node)
+{
+ if (node->data->inputref.inputref)
+ xf86removeInputRef(node->parent->parent->data->layout.layout, node->data->inputref.inputref->iref_inputdev);
+}
+
+/* Vendor */
+static void
+CreateVendor(TreeNode *parent, XF86ConfVendorPtr vendor)
+{
+ TreeNode *prev, *node;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (vendor) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->vendor.vendor = vendor;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = VendorDestroy;
+ CreateVendorField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ vendor = (XF86ConfVendorPtr)(vendor->list.next);
+ }
+
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ CreateVendorField(node, True);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+}
+
+static void
+CreateVendorField(TreeNode *node, Bool addnew)
+{
+ Widget box, command;
+
+ box = XtVaCreateWidget("vendor", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ TreeNode *sub;
+ XF86OptionPtr *options;
+ XF86ConfVendorPtr vendor = node->data->vendor.vendor;
+
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ options = &(vendor->vnd_option_lst);
+ command = XtCreateManagedWidget("options", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
+ XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, vendor->vnd_identifier, NULL, 0);
+
+ command = XtVaCreateManagedWidget("VendSub", toggleWidgetClass, tree,
+ XtNstate, True,
+ XtNtreeParent, box,
+ NULL, 0);
+ sub = NewNode(node, command, command, box, NULL);
+ node->child = sub;
+ CreateVendorSub(sub, vendor->vnd_sub_lst);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, NewVendorCallback, (XtPointer)node);
+ node->data->vendor.text =
+ XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit, NULL, 0);
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+static void
+VendorDestroy(TreeNode *node)
+{
+ if (node->data->vendor.vendor)
+ xf86removeVendor(XF86Config, node->data->vendor.vendor);
+}
+
+static void
+NewVendorCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfVendorPtr vnd;
+ Arg args[1];
+ char *label;
+
+ XtSetArg(args[0], XtNstring, &label);
+ XtGetValues(node->data->vendor.text, args, 1);
+ if (*label == '\0')
+ return;
+
+ parent = node->parent;
+ DeleteNode(node);
+ vnd = (XF86ConfVendorPtr)XtCalloc(1, sizeof(XF86ConfVendorRec));
+ vnd->vnd_identifier = XtNewString(label);
+ XF86Config->conf_vendor_lst = xf86addVendor(XF86Config->conf_vendor_lst, vnd);
+
+ CreateVendor(parent, vnd);
+ RelayoutTree();
+}
+
+/* VendorSub */
+static void
+CreateVendorSub(TreeNode *parent, XF86ConfVendSubPtr vendor)
+{
+ TreeNode *prev, *node;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (vendor) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->vendsub.vendsub = vendor;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = VendorSubDestroy;
+ node->update = VendorSubUpdate;
+ CreateVendorSubField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+ vendor = (XF86ConfVendSubPtr)(vendor->list.next);
+ }
+
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ CreateVendorSubField(node, True);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+}
+
+static void
+CreateVendorSubField(TreeNode *node, Bool addnew)
+{
+ Widget box, command;
+
+ box = XtVaCreateWidget("vendorSub", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ XF86OptionPtr *options;
+ XF86ConfVendSubPtr vendor = node->data->vendsub.vendsub;
+
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+ options = &(vendor->vs_option_lst);
+ command = XtCreateManagedWidget("options", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, OptionsCallback, (XtPointer)options);
+ XtVaCreateManagedWidget("label", labelWidgetClass, box,
+ XtNlabel, vendor->vs_identifier, NULL, 0);
+
+ XtCreateManagedWidget("nameL", labelWidgetClass, box, NULL, 0);
+ node->data->vendsub.text =
+ XtVaCreateManagedWidget("name", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit, XtNstring,
+ vendor->vs_name ? vendor->vs_name : "",
+ NULL, 0);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, NewVendorSubCallback, (XtPointer)node);
+ node->data->vendsub.text =
+ XtVaCreateManagedWidget("value", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit, NULL, 0);
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+static void
+VendorSubDestroy(TreeNode *node)
+{
+ if (node->data->vendsub.vendsub)
+ xf86removeVendorSub(node->parent->parent->data->vendor.vendor,
+ node->data->vendsub.vendsub);
+}
+
+static void
+VendorSubUpdate(TreeNode *node)
+{
+ char *str;
+
+ XtVaGetValues(node->data->vendsub.text, XtNstring, &str, NULL, 0);
+ XtFree(node->data->vendsub.vendsub->vs_name);
+ if (*str)
+ node->data->vendsub.vendsub->vs_name = XtNewString(str);
+ else
+ node->data->vendsub.vendsub->vs_name = NULL;
+}
+
+static void
+NewVendorSubCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfVendSubPtr vnd;
+ Arg args[1];
+ char *label;
+
+ XtSetArg(args[0], XtNstring, &label);
+ XtGetValues(node->data->vendsub.text, args, 1);
+ if (*label == '\0')
+ return;
+
+ parent = node->parent;
+ DeleteNode(node);
+ vnd = (XF86ConfVendSubPtr)XtCalloc(1, sizeof(XF86ConfVendSubRec));
+ vnd->vs_identifier = XtNewString(label);
+ parent->parent->data->vendor.vendor->vnd_sub_lst =
+ xf86addVendorSub(parent->parent->data->vendor.vendor->vnd_sub_lst, vnd);
+
+ CreateVendorSub(parent, vnd);
+ RelayoutTree();
+}
+
+/* DRI */
+static void
+CreateDRI(TreeNode *parent, XF86ConfDRIPtr dri)
+{
+ TreeNode *node;
+ TreeData *data;
+
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->dri.dri = dri;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ parent->child = node;
+ node->update = DRIUpdate;
+ CreateDRIField(node);
+}
+
+static void
+CreateDRIField(TreeNode *node)
+{
+ Widget box, toggle;
+ XF86ConfDRIPtr dri = node->data->dri.dri;
+ TreeNode *buffers;
+ char buf[32];
+
+ box = XtVaCreateWidget("dri", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+ XtCreateManagedWidget("nameL", labelWidgetClass, box, NULL, 0);
+ node->data->dri.name =
+ XtVaCreateManagedWidget("name", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit, XtNstring,
+ dri->dri_group_name ? dri->dri_group_name : "",
+ NULL, 0);
+
+ XtCreateManagedWidget("groupL", labelWidgetClass, box, NULL, 0);
+ if (dri->dri_group >= 0)
+ XmuSnprintf(buf, sizeof(buf), "%d", dri->dri_group);
+ else
+ *buf = '\0';
+ node->data->dri.group =
+ XtVaCreateManagedWidget("group", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit, XtNstring, buf,
+ NULL, 0);
+
+ XtCreateManagedWidget("modeL", labelWidgetClass, box, NULL, 0);
+ if (dri->dri_mode > 0)
+ XmuSnprintf(buf, sizeof(buf), "0%o", dri->dri_mode);
+ else
+ *buf = '\0';
+ node->data->dri.mode =
+ XtVaCreateManagedWidget("mode", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit, XtNstring, buf,
+ NULL, 0);
+
+ toggle = XtVaCreateManagedWidget("Buffers", toggleWidgetClass, tree,
+ XtNstate, True, XtNtreeParent, box,
+ NULL, 0);
+ buffers = NewNode(node, toggle, toggle, box, NULL);
+ node->child = buffers;
+ CreateBuffers(buffers, dri->dri_buffers_lst);
+
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+static void
+DRIUpdate(TreeNode *node)
+{
+ char *str;
+
+ /* name */
+ XtVaGetValues(node->data->dri.name, XtNstring, &str, NULL, 0);
+ XtFree(node->data->dri.dri->dri_group_name);
+ if (*str)
+ node->data->dri.dri->dri_group_name = XtNewString(str);
+ else
+ node->data->dri.dri->dri_group_name = NULL;
+
+ /* group */
+ XtVaGetValues(node->data->dri.group, XtNstring, &str, NULL, 0);
+ if (*str)
+ node->data->dri.dri->dri_group = strtoul(str, NULL, 0);
+ else
+ node->data->dri.dri->dri_group = -1;
+
+ /* mode */
+ XtVaGetValues(node->data->dri.mode, XtNstring, &str, NULL, 0);
+ node->data->dri.dri->dri_mode = strtoul(str, NULL, 0);
+}
+
+/* Buffers */
+static void
+CreateBuffers(TreeNode *parent, XF86ConfBuffersPtr buf)
+{
+ TreeNode *node, *prev;
+ TreeData *data;
+
+ if ((prev = parent->child) != NULL)
+ while (prev->next)
+ prev = prev->next;
+
+ while (buf) {
+ data = (TreeData*)XtCalloc(1, sizeof(TreeData));
+ data->buffers.buffers = buf;
+ node = NewNode(parent, NULL, NULL, parent->node, data);
+ node->destroy = BuffersDestroy;
+ node->update = BuffersUpdate;
+ CreateBuffersField(node, False);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+ prev = node;
+
+ buf = (XF86ConfBuffersPtr)(buf->list.next);
+ }
+ node = NewNode(parent, NULL, NULL, parent->node, NULL);
+ CreateBuffersField(node, True);
+ if (parent->child == NULL)
+ parent->child = node;
+ else
+ prev->next = node;
+}
+
+static void
+CreateBuffersField(TreeNode *node, Bool addnew)
+{
+ Widget box, command;
+
+ box = XtVaCreateWidget("buffers", formWidgetClass, tree,
+ XtNtreeParent, node->treeParent, NULL, 0);
+ node->node = box;
+
+ if (!addnew) {
+ char str[32];
+ XF86ConfBuffersPtr buf = node->data->buffers.buffers;
+
+ command = XtCreateManagedWidget("remove", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, DestroyCallback, (XtPointer)node);
+
+ XtCreateManagedWidget("countL", labelWidgetClass, box, NULL, 0);
+ XmuSnprintf(str, sizeof(str), "%d", buf->buf_count);
+ node->data->buffers.count =
+ XtVaCreateManagedWidget("count", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit, XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("sizeL", labelWidgetClass, box, NULL, 0);
+ XmuSnprintf(str, sizeof(str), "%d", buf->buf_size);
+ node->data->buffers.size =
+ XtVaCreateManagedWidget("size", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit, XtNstring, str,
+ NULL, 0);
+
+ XtCreateManagedWidget("flagsL", labelWidgetClass, box, NULL, 0);
+ node->data->buffers.flags =
+ XtVaCreateManagedWidget("flags", asciiTextWidgetClass, box,
+ XtNeditType, XawtextEdit, XtNstring,
+ buf->buf_flags ? buf->buf_flags : "",
+ NULL, 0);
+ }
+ else {
+ command = XtCreateManagedWidget("new", commandWidgetClass, box,
+ NULL, 0);
+ XtAddCallback(command, XtNcallback, NewBuffersCallback, (XtPointer)node);
+ }
+ if (XtIsRealized(node->treeParent))
+ XtRealizeWidget(box);
+ XtManageChild(box);
+}
+
+/*ARGUSED*/
+static void
+BuffersDestroy(TreeNode *node)
+{
+ if (node->data->buffers.buffers)
+ xf86removeBuffers(XF86Config->conf_dri, node->data->buffers.buffers);
+}
+
+/*ARGSUSED*/
+static void
+NewBuffersCallback(Widget unused, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *parent, *node = (TreeNode*)user_data;
+ XF86ConfBuffersPtr buf;
+
+ parent = node->parent;
+ DeleteNode(node);
+ buf = (XF86ConfBuffersPtr)XtCalloc(1, sizeof(XF86ConfBuffersRec));
+ XF86Config->conf_dri->dri_buffers_lst =
+ xf86addBuffers(XF86Config->conf_dri->dri_buffers_lst, buf);
+
+ CreateBuffers(parent, buf);
+ RelayoutTree();
+}
+
+static void
+BuffersUpdate(TreeNode *node)
+{
+ char *str;
+
+ /* count */
+ XtVaGetValues(node->data->buffers.count, XtNstring, &str, NULL, 0);
+ node->data->buffers.buffers->buf_count = strtoul(str, NULL, 0);
+
+ /* size */
+ XtVaGetValues(node->data->buffers.size, XtNstring, &str, NULL, 0);
+ node->data->buffers.buffers->buf_size = strtoul(str, NULL, 0);
+
+ /* flags */
+ XtVaGetValues(node->data->buffers.flags, XtNstring, &str, NULL, 0);
+ if (*str)
+ node->data->buffers.buffers->buf_flags = XtNewString(str);
+ else
+ node->data->buffers.buffers->buf_flags = NULL;
+}
+
+static TreeNode *
+NewNode(TreeNode *parent, Widget node, Widget toggle, Widget treeParent,
+ TreeData *data)
+{
+ TreeNode *tree = (TreeNode*)XtCalloc(1, sizeof(TreeNode));
+
+ tree->parent = parent;
+ tree->node = node;
+ if ((tree->toggle = toggle) != NULL)
+ XtAddCallback(toggle, XtNcallback, ToggleCallback, (XtPointer)tree);
+ tree->treeParent = treeParent;
+ tree->data = data;
+
+ return (tree);
+}
+
+static void
+DeleteNode(TreeNode *node)
+{
+ TreeNode *ptr = node->child;
+
+ while (ptr != NULL) {
+ TreeNode *next = ptr->next;
+
+ DeleteNode(ptr);
+ ptr = next;
+ }
+
+ if (node->parent && node->parent->child == node)
+ node->parent->child = node->next;
+ else if (node->parent) {
+ for (ptr = node->parent->child; ptr && ptr->next != node;
+ ptr = ptr->next)
+ ;
+ if (ptr)
+ ptr->next = node->next;
+ }
+
+ if (node->destroy)
+ (node->destroy)(node);
+ if (node->data)
+ XtFree((XtPointer)node->data);
+
+ /* sets treeParent to NULL so that RelayoutTree works correctly,
+ * as the tree will properly calculate it's new size.
+ */
+ XtVaSetValues(node->node, XtNtreeParent, NULL, NULL, 0);
+
+ XtDestroyWidget(node->node);
+ XtFree((XtPointer)node);
+}
+
+/*ARGUSED*/
+static void
+DestroyCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *node = (TreeNode*)user_data;
+
+ DeleteNode(node);
+ RelayoutTree();
+}
+
+static void
+ToggleNodeRecursive(TreeNode *node)
+{
+ while (node) {
+ if (!XtIsRealized(node->node))
+ XtRealizeWidget(node->node);
+ XtVaSetValues(node->node, XtNtreeParent, node->treeParent, NULL, 0);
+ XtManageChild(node->node);
+
+ if (node->child && !node->toggle)
+ ToggleNodeRecursive(node->child);
+
+ node = node->next;
+ }
+}
+
+static void
+ToggleNode(TreeNode *node, Bool toggle)
+{
+ while (node) {
+ if (toggle) {
+ if (!XtIsRealized(node->node))
+ XtRealizeWidget(node->node);
+ XtVaSetValues(node->node, XtNtreeParent, node->treeParent, NULL, 0);
+ XtManageChild(node->node);
+
+ if (node->child && !node->toggle)
+ ToggleNodeRecursive(node->child);
+ }
+ else {
+ if (node->child)
+ ToggleNode(node->child, False);
+ XtVaSetValues(node->node, XtNtreeParent, NULL, NULL, 0);
+ XtUnmanageChild(node->node);
+ if (node->toggle)
+ XtVaSetValues(node->toggle, XtNstate, False, NULL, 0);
+ }
+ node = node->next;
+ }
+}
+
+/*
+ * XXX This callback can show side effects in the way it is called. If
+ * the structure holding the XF86OptionPtr is reallocated, a bogus pointer
+ * will be passed to this callback.
+ */
+static void
+OptionsCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XF86OptionPtr *options = (XF86OptionPtr*)user_data;
+
+#ifdef USE_MODULES
+ OptionsPopup(options, NULL, NULL);
+#else
+ OptionsPopup(options);
+#endif
+}
+
+static void
+RelayoutTree(void)
+{
+ Arg args[4];
+ Dimension sliderWidth, sliderHeight, canvasWidth, canvasHeight;
+
+ XtSetArg(args[0], XtNwidth, &sliderWidth);
+ XtSetArg(args[1], XtNheight, &sliderHeight);
+ XtGetValues(shell, args, 2);
+
+ XtSetArg(args[2], XtNwidth, &canvasWidth);
+ XtSetArg(args[3], XtNheight, &canvasHeight);
+ XtGetValues(tree, args + 2, 2);
+
+ XtSetArg(args[0], XtNsliderWidth, sliderWidth);
+ XtSetArg(args[1], XtNsliderHeight, sliderHeight);
+ XtSetArg(args[2], XtNcanvasWidth, canvasWidth);
+ XtSetArg(args[3], XtNcanvasHeight, canvasHeight);
+ XtSetValues(panner, args, 4);
+}
+
+static void
+ToggleCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ TreeNode *nodeParent = (TreeNode*)user_data;
+
+ if (nodeParent->child) {
+ if (XtIsRealized(tree))
+ XtUnmapWidget(tree);
+ ToggleNode(nodeParent->child, (Bool)(long)call_data);
+ RelayoutTree();
+ if (XtIsRealized(tree))
+ XtMapWidget(tree);
+ }
+}
+
+/*ARGSUSED*/
+static void
+PannerCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[2];
+ XawPannerReport *rep = (XawPannerReport *)call_data;
+
+ XtSetArg (args[0], XtNx, -rep->slider_x);
+ XtSetArg (args[1], XtNy, -rep->slider_y);
+ XtSetValues(tree, args, 2);
+}
+
+/*ARGSUSED*/
+static void
+PortholeCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XawPannerReport *rep = (XawPannerReport*)call_data;
+ Arg args[6];
+ Cardinal n = 2;
+
+ XtSetArg (args[0], XtNsliderX, rep->slider_x);
+ XtSetArg (args[1], XtNsliderY, rep->slider_y);
+ if (rep->changed != (XawPRSliderX | XawPRSliderY)) {
+ XtSetArg (args[2], XtNsliderWidth, rep->slider_width);
+ XtSetArg (args[3], XtNsliderHeight, rep->slider_height);
+ XtSetArg (args[4], XtNcanvasWidth, rep->canvas_width);
+ XtSetArg (args[5], XtNcanvasHeight, rep->canvas_height);
+ n = 6;
+ }
+ XtSetValues(panner, args, n);
+}
+
+static void
+DestroyTree(TreeNode *node)
+{
+ while (node) {
+ TreeNode *next = node->next;
+ if (node->child)
+ DestroyTree(node->child);
+
+ if (node->data)
+ XtFree((XtPointer)node->data);
+ XtFree((XtPointer)node);
+
+ node = next;
+ }
+}
+
+static void
+UpdateConfig(TreeNode *node)
+{
+ while (node) {
+ if (node->child)
+ UpdateConfig(node->child);
+ if (node->update)
+ (node->update)(node);
+ node = node->next;
+ }
+}
+
+static Bool
+ExpertInitialize(void)
+{
+ Widget paned, vpane, close, config, files, modules, flags, video, modes,
+ monitor, device, screen, input, layout, vendor, dri;
+ Arg args[4];
+ Dimension width, height, canvasWidth, canvasHeight;
+ TreeNode *node;
+
+ if (expert != NULL)
+ return (False);
+
+ shell = XtCreatePopupShell("Expert", transientShellWidgetClass,
+ toplevel, NULL, 0);
+ paned = XtVaCreateManagedWidget("paned", panedWidgetClass, shell,
+ XtNorientation, XtorientHorizontal, NULL, 0);
+ vpane = XtCreateManagedWidget("vpane", panedWidgetClass, paned, NULL, 0);
+ panner = XtCreateManagedWidget ("panner", pannerWidgetClass, vpane, NULL, 0);
+ close = XtCreateManagedWidget("close", commandWidgetClass, vpane, NULL, 0);
+ XtAddCallback(close, XtNcallback, PopdownCallback, NULL);
+
+ expert = XtCreateManagedWidget("expert", portholeWidgetClass, paned, NULL, 0);
+ XtAddCallback(expert, XtNreportCallback, PortholeCallback, NULL);
+ XtAddCallback(panner, XtNreportCallback, PannerCallback, NULL);
+ tree = XtCreateManagedWidget("tree", treeWidgetClass, expert, NULL, 0);
+
+ config = XtVaCreateManagedWidget("XF86Config", toggleWidgetClass, tree,
+ XtNstate, True, NULL, 0);
+ mainNode = NewNode(NULL, config, config, NULL, NULL);
+
+ files = XtVaCreateManagedWidget("Files", toggleWidgetClass, tree,
+ XtNtreeParent, config, NULL, 0);
+ node = NewNode(mainNode, files, files, config, NULL);
+ mainNode->child = node;
+ CreateFiles(node);
+
+ modules = XtVaCreateManagedWidget("Module", toggleWidgetClass, tree,
+ XtNtreeParent, config, NULL, 0);
+ node->next = NewNode(mainNode, modules, modules, config, NULL);
+ node = node->next;
+ CreateModule(node, XF86Config->conf_modules ?
+ XF86Config->conf_modules->mod_load_lst : NULL);
+
+ flags = XtVaCreateManagedWidget("ServerFlags", commandWidgetClass, tree,
+ XtNtreeParent, config, NULL, 0);
+ node->next = NewNode(mainNode, flags, NULL, config, NULL);
+ node = node->next;
+ if (XF86Config->conf_flags == NULL)
+ XF86Config->conf_flags = (XF86ConfFlagsPtr)
+ XtCalloc(1, sizeof(XF86ConfFlagsRec));
+ XtAddCallback(flags, XtNcallback, OptionsCallback,
+ (XtPointer)&(XF86Config->conf_flags->flg_option_lst));
+
+ video = XtVaCreateManagedWidget("VideoAdaptor", toggleWidgetClass, tree,
+ XtNtreeParent, config, NULL, 0);
+ node->next = NewNode(mainNode, video, video, config, NULL);
+ node = node->next;
+ CreateVideoAdaptor(node, XF86Config->conf_videoadaptor_lst);
+
+ modes = XtVaCreateManagedWidget("Mode", toggleWidgetClass, tree,
+ XtNtreeParent, config, NULL, 0);
+ node->next = NewNode(mainNode, modes, modes, config, NULL);
+ node = node->next;
+ CreateModes(node, XF86Config->conf_modes_lst);
+
+ monitor = XtVaCreateManagedWidget("Monitor", toggleWidgetClass, tree,
+ XtNtreeParent, config, NULL, 0);
+ node->next = NewNode(mainNode, monitor, monitor, config, NULL);
+ node = node->next;
+ CreateMonitor(monitorTree = node, XF86Config->conf_monitor_lst);
+
+ device = XtVaCreateManagedWidget("Device", toggleWidgetClass, tree,
+ XtNtreeParent, config, NULL, 0);
+ node->next = NewNode(mainNode, device, device, config, NULL);
+ node = node->next;
+ CreateDevice(node, XF86Config->conf_device_lst);
+
+ screen = XtVaCreateManagedWidget("Screen", toggleWidgetClass, tree,
+ XtNtreeParent, config, NULL, 0);
+ node->next = NewNode(mainNode, screen, screen, config, NULL);
+ node = node->next;
+ CreateScreen(screenTree = node, XF86Config->conf_screen_lst);
+
+ input = XtVaCreateManagedWidget("Input", toggleWidgetClass, tree,
+ XtNtreeParent, config, NULL, 0);
+ node->next = NewNode(mainNode, input, input, config, NULL);
+ node = node->next;
+ CreateInput(node, XF86Config->conf_input_lst);
+
+ layout = XtVaCreateManagedWidget("Layout", toggleWidgetClass, tree,
+ XtNtreeParent, config, NULL, 0);
+ node->next = NewNode(mainNode, layout, layout, config, NULL);
+ node = node->next;
+ CreateLayout(layoutTree = node, XF86Config->conf_layout_lst);
+
+ vendor = XtVaCreateManagedWidget("Vendor", toggleWidgetClass, tree,
+ XtNtreeParent, config, NULL, 0);
+ node->next = NewNode(mainNode, vendor, vendor, config, NULL);
+ node = node->next;
+ CreateVendor(node, XF86Config->conf_vendor_lst);
+
+ dri = XtVaCreateManagedWidget("DRI", toggleWidgetClass, tree,
+ XtNtreeParent, config, NULL, 0);
+ node->next = NewNode(mainNode, dri, dri, config, NULL);
+ node = node->next;
+ if (XF86Config->conf_dri == NULL)
+ XF86Config->conf_dri = (XF86ConfDRIPtr)
+ XtCalloc(1, sizeof(XF86ConfDRIRec));
+ CreateDRI(node, XF86Config->conf_dri);
+
+ XtRealizeWidget(shell);
+
+ XtSetArg(args[0], XtNwidth, &width);
+ XtSetArg(args[1], XtNheight, &height);
+ XtGetValues(shell, args, 2);
+ XtSetArg(args[0], XtNwidth, width);
+ XtSetArg(args[1], XtNheight, height);
+ XtSetValues(expert, args, 2);
+
+ XtSetArg(args[0], XtNsliderWidth, width);
+ XtSetArg(args[1], XtNsliderHeight, height);
+ XtSetArg(args[2], XtNwidth, &canvasWidth);
+ XtSetArg(args[3], XtNheight, &canvasHeight);
+ XtGetValues(tree, args + 2, 2);
+ XtSetArg(args[2], XtNcanvasWidth, canvasWidth);
+ XtSetArg(args[3], XtNcanvasHeight, canvasHeight);
+ XtSetValues(panner, args, 4);
+
+ /* needs to do the apparently NOP code bellow to correctly layout the
+ * tree widget */
+
+ /* close all open entries */
+ ToggleCallback(config, mainNode, (XtPointer)0);
+ /* open first level */
+ ToggleCallback(config, mainNode, (XtPointer)1);
+
+ XSetWMProtocols(DPY, XtWindow(shell), &wm_delete_window, 1);
+
+ return (True);
+}