summaryrefslogtreecommitdiff
path: root/hw/xfree86/utils/xorgcfg
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:57 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:57 +0000
commit9508a382f8a9f241dab097d921b6d290c1c3a776 (patch)
treefa456480bae7040c3f971a70b390f2d091c680b5 /hw/xfree86/utils/xorgcfg
parentded6147bfb5d75ff1e67c858040a628b61bc17d1 (diff)
Initial revision
Diffstat (limited to 'hw/xfree86/utils/xorgcfg')
-rw-r--r--hw/xfree86/utils/xorgcfg/TODO33
-rw-r--r--hw/xfree86/utils/xorgcfg/accessx.c682
-rw-r--r--hw/xfree86/utils/xorgcfg/card-cfg.c434
-rw-r--r--hw/xfree86/utils/xorgcfg/card-cfg.h44
-rw-r--r--hw/xfree86/utils/xorgcfg/card.xbm59
-rw-r--r--hw/xfree86/utils/xorgcfg/card.xpm81
-rw-r--r--hw/xfree86/utils/xorgcfg/cards.c693
-rw-r--r--hw/xfree86/utils/xorgcfg/cards.h90
-rw-r--r--hw/xfree86/utils/xorgcfg/computer.xpm91
-rw-r--r--hw/xfree86/utils/xorgcfg/config.c302
-rw-r--r--hw/xfree86/utils/xorgcfg/config.h227
-rw-r--r--hw/xfree86/utils/xorgcfg/down.xbm8
-rw-r--r--hw/xfree86/utils/xorgcfg/expert.c4860
-rw-r--r--hw/xfree86/utils/xorgcfg/help.c1786
-rw-r--r--hw/xfree86/utils/xorgcfg/help.h42
-rw-r--r--hw/xfree86/utils/xorgcfg/interface.c2280
-rw-r--r--hw/xfree86/utils/xorgcfg/keyboard-cfg.c1379
-rw-r--r--hw/xfree86/utils/xorgcfg/keyboard-cfg.h74
-rw-r--r--hw/xfree86/utils/xorgcfg/keyboard.xbm59
-rw-r--r--hw/xfree86/utils/xorgcfg/keyboard.xpm66
-rw-r--r--hw/xfree86/utils/xorgcfg/left.xbm8
-rw-r--r--hw/xfree86/utils/xorgcfg/loader.c396
-rw-r--r--hw/xfree86/utils/xorgcfg/loader.h171
-rw-r--r--hw/xfree86/utils/xorgcfg/loadmod.c658
-rw-r--r--hw/xfree86/utils/xorgcfg/monitor-cfg.c449
-rw-r--r--hw/xfree86/utils/xorgcfg/monitor-cfg.h48
-rw-r--r--hw/xfree86/utils/xorgcfg/monitor.xbm59
-rw-r--r--hw/xfree86/utils/xorgcfg/monitor.xpm79
-rw-r--r--hw/xfree86/utils/xorgcfg/mouse-cfg.c450
-rw-r--r--hw/xfree86/utils/xorgcfg/mouse-cfg.h44
-rw-r--r--hw/xfree86/utils/xorgcfg/mouse.xbm59
-rw-r--r--hw/xfree86/utils/xorgcfg/mouse.xpm76
-rw-r--r--hw/xfree86/utils/xorgcfg/narrower.xbm8
-rw-r--r--hw/xfree86/utils/xorgcfg/options.c788
-rw-r--r--hw/xfree86/utils/xorgcfg/options.h51
-rw-r--r--hw/xfree86/utils/xorgcfg/right.xbm8
-rw-r--r--hw/xfree86/utils/xorgcfg/screen-cfg.c552
-rw-r--r--hw/xfree86/utils/xorgcfg/screen-cfg.h44
-rw-r--r--hw/xfree86/utils/xorgcfg/screen.c984
-rw-r--r--hw/xfree86/utils/xorgcfg/screen.h52
-rw-r--r--hw/xfree86/utils/xorgcfg/shorter.xbm8
-rw-r--r--hw/xfree86/utils/xorgcfg/startx.c150
-rw-r--r--hw/xfree86/utils/xorgcfg/stubs.c65
-rw-r--r--hw/xfree86/utils/xorgcfg/stubs.h43
-rw-r--r--hw/xfree86/utils/xorgcfg/taller.xbm8
-rw-r--r--hw/xfree86/utils/xorgcfg/text-mode.c3353
-rw-r--r--hw/xfree86/utils/xorgcfg/up.xbm8
-rw-r--r--hw/xfree86/utils/xorgcfg/vidmode.c1357
-rw-r--r--hw/xfree86/utils/xorgcfg/vidmode.h64
-rw-r--r--hw/xfree86/utils/xorgcfg/wider.xbm8
-rw-r--r--hw/xfree86/utils/xorgcfg/xf86config.c980
-rw-r--r--hw/xfree86/utils/xorgcfg/xf86config.h111
52 files changed, 24429 insertions, 0 deletions
diff --git a/hw/xfree86/utils/xorgcfg/TODO b/hw/xfree86/utils/xorgcfg/TODO
new file mode 100644
index 000000000..75fe91b95
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/TODO
@@ -0,0 +1,33 @@
+$XFree86: xc/programs/Xserver/hw/xfree86/xf86cfg/TODO,v 1.1 2001/07/04 16:09:14 paulo Exp $
+
+o Have code to fetch the SymTabRec chipset list from a video driver.
+ This is mostly useful for the testing tool/interface, so that the
+ Cards file "uptodate" state can also be verified.
+ Probably it is better to forgot about the Cards file, and
+ either parse the output of scanpci, or link libscanpci.a
+ (and whatever else be required) in xf86cfg.
+
+o Check if a module is "certified", there was some talk about a
+ certification process in the past.
+
+o Rewrite mouse driver to use the same code as video drivers, so that
+ it is possible to store all available options in a single place.
+ This would also require rewriting all existing input device modules.
+ (Probably most of this can be made with cpp macros).
+
+o Create a protocol to allow 3rd part xf86cfg modules.
+
+o Write an interface for testing extensions/accel, maybe a frontend to
+ xdpyinfo, x11perf, glxinfo, etc.
+
+o Write a "wizard" mode, as several users find the graphical interface
+ too complicated, but find the text one easier to user.
+
+o Write code to use a Monitors database, either update the old Monitors
+ file or use RedHat MonitorsDB.
+ Chris Morgan is writting code to use MonitorsDB.
+ If xf86cfg could be changed to ddcprobe (in all supported platforms),
+ it would be even be a better solution than using a database.
+
+o Add interface to allow changing comments without the need of editing
+ XF86Config with a text editor.
diff --git a/hw/xfree86/utils/xorgcfg/accessx.c b/hw/xfree86/utils/xorgcfg/accessx.c
new file mode 100644
index 000000000..40727ff62
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/accessx.c
@@ -0,0 +1,682 @@
+/*
+ * 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/accessx.c,v 1.10 2002/12/05 19:31:18 paulo Exp $
+ */
+
+#include "config.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <X11/XKBlib.h>
+#include <X11/Shell.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/Scrollbar.h>
+#include <X11/Xaw/Toggle.h>
+#include "keyboard-cfg.h"
+
+#define MAX_TIMEOUT 20
+#define MAX_MOUSE_SPEED 500
+#define MAX_MOUSE_TIME 4
+#define MAX_MOUSE_DELAY 2.09
+#define MAX_REPEAT_RATE 8.04
+#define MAX_REPEAT_DELAY 6.04
+#define MAX_SLOW_TIME 4
+#define MAX_BOUNCE_TIME 4
+
+/*
+ * Types
+ */
+typedef struct {
+ Widget label, number, scroller;
+ double min, max, value, resolution;
+ Bool integer;
+} Scale;
+
+/*
+ * Initialization
+ */
+static Widget shell, accessx, enable, timeoutToggle, form, apply;
+static Widget sticky, stickyAuto, stickyBeep;
+static Widget mouse;
+static Widget repeat;
+static Widget slowToggle, slowPressed, slowAccepted;
+static Widget bounceToggle;
+static Scale *timeout, *mouseSpeed, *mouseTime, *mouseDelay, *slow,
+ *repeatRate, *repeatDelay, *bounce;
+extern Widget work;
+
+/*
+ * Prototypes
+ */
+static void CreateAccessXHelpDialog(void);
+static void EnableCallback(Widget, XtPointer, XtPointer);
+static void ScaleEnableCallback(Widget, XtPointer, XtPointer);
+static void ScaleJumpCallback(Widget, XtPointer, XtPointer);
+
+static void ApplyCallback(Widget, XtPointer, XtPointer);
+static void AccessXInitialize(void);
+
+void CloseAccessXAction(Widget, XEvent*, String*, Cardinal*);
+void AccessXConfigureStart(void);
+void AccessXConfigureEnd(void);
+
+/*
+ * Implementation
+ */
+void
+startaccessx(void)
+{
+ InitializeKeyboard();
+
+ if (xkb_info->xkb) {
+ XkbGetControls(DPY, XkbAllControlsMask, xkb_info->xkb);
+ if (xkb_info->xkb->ctrls == NULL)
+ xkb_info->xkb->ctrls = (XkbControlsPtr)
+ XtCalloc(1, sizeof(XkbControlsRec));
+
+ xkb_info->xkb->ctrls->enabled_ctrls |= XkbMouseKeysMask |
+ XkbMouseKeysAccelMask;
+ xkb_info->xkb->ctrls->mk_delay = 40;
+ xkb_info->xkb->ctrls->mk_interval = 10;
+ xkb_info->xkb->ctrls->mk_time_to_max = 1000;
+ xkb_info->xkb->ctrls->mk_max_speed = 500;
+ xkb_info->xkb->ctrls->mk_curve = 0;
+ XkbSetControls(DPY, XkbAllControlsMask, xkb_info->xkb);
+ (void)UpdateKeyboard(True);
+ CreateAccessXHelpDialog();
+ }
+}
+
+void
+CreateAccessXHelpDialog()
+{
+ Widget form;
+
+ shell = XtVaCreatePopupShell("accessx", transientShellWidgetClass, toplevel,
+ XtNx, toplevel->core.x + toplevel->core.width,
+ XtNy, toplevel->core.y, NULL, 0);
+ form = XtCreateManagedWidget("form", formWidgetClass, shell, NULL, 0);
+ XtCreateManagedWidget("label", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("lock", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("div", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("mul", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("minus", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("7", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("8", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("9", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("plus", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("4", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("5", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("6", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("1", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("2", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("3", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("enter", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("0", labelWidgetClass, form, NULL, 0);
+ XtCreateManagedWidget("del", labelWidgetClass, form, NULL, 0);
+
+ XtRealizeWidget(shell);
+ XSetWMProtocols(DPY, XtWindow(shell), &wm_delete_window, 1);
+ XtPopup(shell, XtGrabNone);
+}
+
+/*ARGSUSED*/
+void
+CloseAccessXAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+ XtPopdown(shell);
+}
+
+static void
+AccessXInitialize(void)
+{
+ static int first = 1;
+ Arg args[1];
+ Boolean state;
+ Widget stickyForm, mouseForm, repeatForm, slowForm, bounceForm;
+ float val, tmp;
+
+ if (!first)
+ return;
+ first = 0;
+
+ InitializeKeyboard();
+
+ XkbGetControls(DPY, XkbAllControlsMask, xkb_info->xkb);
+ if (xkb_info->xkb->ctrls == NULL)
+ xkb_info->xkb->ctrls = (XkbControlsPtr)
+ XtCalloc(1, sizeof(XkbControlsRec));
+
+ timeout = XtNew(Scale);
+ accessx = XtCreateWidget("accessxForm", formWidgetClass, work, NULL, 0);
+ enable = XtVaCreateManagedWidget("enable", toggleWidgetClass, accessx,
+ XtNstate,
+ (xkb_info->xkb->ctrls->enabled_ctrls &
+ (XkbAccessXKeysMask | XkbStickyKeysMask |
+ XkbSlowKeysMask | XkbBounceKeysMask)) != 0, NULL, 0);
+
+ apply = XtCreateManagedWidget("apply", commandWidgetClass, accessx, NULL, 0);
+ XtAddCallback(apply, XtNcallback, ApplyCallback, NULL);
+
+ form = XtCreateManagedWidget("Accessx", formWidgetClass, accessx, NULL, 0);
+ timeoutToggle = XtVaCreateManagedWidget("timeoutToggle", toggleWidgetClass,
+ form, XtNstate,
+ xkb_info->xkb->ctrls->ax_timeout > 60
+ && xkb_info->xkb->ctrls->ax_timeout
+ < 30000, NULL, 0);
+ XtAddCallback(timeoutToggle, XtNcallback, ScaleEnableCallback,
+ (XtPointer)timeout);
+ timeout->label = XtCreateManagedWidget("timeoutLabel", labelWidgetClass,
+ form, NULL, 0);
+ timeout->number = XtCreateManagedWidget("timeoutNumber", labelWidgetClass,
+ form, NULL, 0);
+ timeout->scroller = XtCreateManagedWidget("timeoutScroller",
+ scrollbarWidgetClass,
+ form, NULL, 0);
+ XtAddCallback(timeout->scroller, XtNjumpProc, ScaleJumpCallback,
+ (XtPointer)timeout);
+ timeout->min = 1;
+ timeout->max = MAX_TIMEOUT;
+ timeout->resolution = 1;
+ timeout->integer = True;
+
+ sticky = XtVaCreateManagedWidget("sticky", toggleWidgetClass, form,
+ XtNstate,
+ (xkb_info->xkb->ctrls->enabled_ctrls &
+ XkbStickyKeysMask) != 0, NULL, 0);
+ stickyForm = XtCreateManagedWidget("stickyForm", formWidgetClass,
+ form, NULL, 0);
+ XtAddCallback(sticky, XtNcallback, EnableCallback, (XtPointer)stickyForm);
+ stickyAuto = XtVaCreateManagedWidget("auto", toggleWidgetClass, stickyForm,
+ XtNstate,
+ (xkb_info->xkb->ctrls->ax_options &
+ XkbAX_LatchToLockMask) == 0, NULL, 0);
+ stickyBeep = XtVaCreateManagedWidget("beep", toggleWidgetClass, stickyForm,
+ XtNstate,
+ (xkb_info->xkb->ctrls->ax_options &
+ XkbAX_StickyKeysFBMask) != 0, NULL, 0);
+
+ mouse = XtVaCreateManagedWidget("mouseKeys", toggleWidgetClass, form,
+ XtNstate,
+ (xkb_info->xkb->ctrls->enabled_ctrls &
+ (XkbMouseKeysMask | XkbMouseKeysAccelMask))
+ != 0, NULL, 0);
+ mouseForm = XtCreateManagedWidget("mouseForm", formWidgetClass,
+ form, NULL, 0);
+ XtAddCallback(mouse, XtNcallback, EnableCallback, (XtPointer)mouseForm);
+ mouseSpeed = XtNew(Scale);
+ mouseSpeed->label = XtCreateManagedWidget("speedLabel", labelWidgetClass,
+ mouseForm, NULL, 0);
+ mouseSpeed->number = XtCreateManagedWidget("speedNumber", labelWidgetClass,
+ mouseForm, NULL, 0);
+ mouseSpeed->scroller = XtCreateManagedWidget("speedScroller",
+ scrollbarWidgetClass,
+ mouseForm, NULL, 0);
+ XtAddCallback(mouseSpeed->scroller, XtNjumpProc, ScaleJumpCallback,
+ (XtPointer)mouseSpeed);
+ mouseSpeed->min = 10;
+ mouseSpeed->max = MAX_MOUSE_SPEED;
+ mouseSpeed->resolution = 10;
+ mouseSpeed->integer = True;
+ mouseTime = XtNew(Scale);
+ mouseTime->label = XtCreateManagedWidget("timeLabel", labelWidgetClass,
+ mouseForm, NULL, 0);
+ mouseTime->number = XtCreateManagedWidget("timeNumber", labelWidgetClass,
+ mouseForm, NULL, 0);
+ mouseTime->scroller = XtCreateManagedWidget("timeScroller",
+ scrollbarWidgetClass,
+ mouseForm, NULL, 0);
+ XtAddCallback(mouseTime->scroller, XtNjumpProc, ScaleJumpCallback,
+ (XtPointer)mouseTime);
+ mouseTime->min = .1;
+ mouseTime->max = MAX_MOUSE_TIME;
+ mouseTime->resolution = .1;
+ mouseTime->integer = False;
+ mouseDelay = XtNew(Scale);
+ mouseDelay->label = XtCreateManagedWidget("delayLabel", labelWidgetClass,
+ mouseForm, NULL, 0);
+ mouseDelay->number = XtCreateManagedWidget("delayNumber", labelWidgetClass,
+ mouseForm, NULL, 0);
+ mouseDelay->scroller = XtCreateManagedWidget("delayScroller",
+ scrollbarWidgetClass,
+ mouseForm, NULL, 0);
+ XtAddCallback(mouseDelay->scroller, XtNjumpProc, ScaleJumpCallback,
+ (XtPointer)mouseDelay);
+ mouseDelay->min = .1;
+ mouseDelay->max = MAX_MOUSE_DELAY;
+ mouseDelay->resolution = .1;
+ mouseDelay->integer = False;
+
+ repeat = XtVaCreateManagedWidget("repeatKeys", toggleWidgetClass, form,
+ XtNstate,
+ (xkb_info->xkb->ctrls->enabled_ctrls &
+ XkbRepeatKeysMask) != 0, NULL, 0);
+ repeatForm = XtCreateManagedWidget("repeatForm", formWidgetClass,
+ form, NULL, 0);
+ XtAddCallback(repeat, XtNcallback, EnableCallback, (XtPointer)repeatForm);
+ repeatRate = XtNew(Scale);
+ repeatRate->label = XtCreateManagedWidget("rateLabel", labelWidgetClass,
+ repeatForm, NULL, 0);
+ repeatRate->number = XtCreateManagedWidget("rateNumber", labelWidgetClass,
+ repeatForm, NULL, 0);
+ repeatRate->scroller = XtCreateManagedWidget("rateScroller",
+ scrollbarWidgetClass,
+ repeatForm, NULL, 0);
+ XtAddCallback(repeatRate->scroller, XtNjumpProc, ScaleJumpCallback,
+ (XtPointer)repeatRate);
+ repeatRate->min = .05;
+ repeatRate->max = MAX_REPEAT_RATE;
+ repeatRate->resolution = .05;
+ repeatRate->integer = False;
+ repeatDelay = XtNew(Scale);
+ repeatDelay->label = XtCreateManagedWidget("delayLabel", labelWidgetClass,
+ repeatForm, NULL, 0);
+ repeatDelay->number = XtCreateManagedWidget("delayNumber", labelWidgetClass,
+ repeatForm, NULL, 0);
+ repeatDelay->scroller = XtCreateManagedWidget("delayScroller",
+ scrollbarWidgetClass,
+ repeatForm, NULL, 0);
+ XtAddCallback(repeatDelay->scroller, XtNjumpProc, ScaleJumpCallback,
+ (XtPointer)repeatDelay);
+ repeatDelay->min = .05;
+ repeatDelay->max = MAX_REPEAT_DELAY;
+ repeatDelay->resolution = .05;
+ repeatDelay->integer = False;
+
+ slowToggle = XtVaCreateManagedWidget("slow", toggleWidgetClass,
+ form, XtNstate,
+ (xkb_info->xkb->ctrls->enabled_ctrls &
+ XkbSlowKeysMask) != 0, NULL, 0);
+ slowForm = XtCreateManagedWidget("slowForm", formWidgetClass,
+ form, NULL, 0);
+ XtAddCallback(slowToggle, XtNcallback, EnableCallback, (XtPointer)slowForm);
+ XtCreateManagedWidget("beep", labelWidgetClass, slowForm, NULL, 0);
+ slowPressed = XtVaCreateManagedWidget("pressed", toggleWidgetClass,
+ slowForm, XtNstate,
+ (xkb_info->xkb->ctrls->ax_options &
+ XkbAX_SKPressFBMask) != 0,
+ NULL, 0);
+ slowAccepted = XtVaCreateManagedWidget("accepted", toggleWidgetClass,
+ slowForm, XtNstate,
+ (xkb_info->xkb->ctrls->ax_options &
+ XkbAX_SKAcceptFBMask) != 0,
+ NULL, 0);
+ slow = XtNew(Scale);
+ slow->label = XtCreateManagedWidget("slowLabel", labelWidgetClass,
+ slowForm, NULL, 0);
+ slow->number = XtCreateManagedWidget("slowNumber", labelWidgetClass,
+ slowForm, NULL, 0);
+ slow->scroller = XtCreateManagedWidget("slowScroller",
+ scrollbarWidgetClass,
+ slowForm, NULL, 0);
+ XtAddCallback(slow->scroller, XtNjumpProc, ScaleJumpCallback,
+ (XtPointer)slow);
+ slow->min = 0.1;
+ slow->max = MAX_SLOW_TIME;
+ slow->resolution = 0.1;
+ slow->integer = False;
+
+ bounceToggle = XtVaCreateManagedWidget("bounce", toggleWidgetClass,
+ form, XtNstate,
+ (xkb_info->xkb->ctrls->enabled_ctrls &
+ XkbBounceKeysMask) != 0,
+ NULL, 0);
+ bounceForm = XtCreateManagedWidget("bounceForm", formWidgetClass,
+ form, NULL, 0);
+ XtAddCallback(bounceToggle, XtNcallback, EnableCallback, (XtPointer)bounceForm);
+ bounce = XtNew(Scale);
+ bounce->label = XtCreateManagedWidget("bounceLabel", labelWidgetClass,
+ bounceForm, NULL, 0);
+ bounce->number = XtCreateManagedWidget("bounceNumber", labelWidgetClass,
+ bounceForm, NULL, 0);
+ bounce->scroller = XtCreateManagedWidget("bounceScroller",
+ scrollbarWidgetClass,
+ bounceForm, NULL, 0);
+ XtAddCallback(bounce->scroller, XtNjumpProc, ScaleJumpCallback,
+ (XtPointer)bounce);
+ bounce->min = 0.1;
+ bounce->max = MAX_BOUNCE_TIME;
+ bounce->resolution = 0.1;
+ bounce->integer = False;
+
+ XtRealizeWidget(accessx);
+
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(timeoutToggle, args, 1);
+ ScaleEnableCallback(enable, (XtPointer)timeout, (XtPointer)(long)state);
+ if (xkb_info->xkb->ctrls->ax_timeout > 60)
+ val = (float)(xkb_info->xkb->ctrls->ax_timeout - 60) /
+ (float)(MAX_TIMEOUT * 60);
+ else
+ val = 0;
+ ScaleJumpCallback(timeout->scroller, (XtPointer)timeout, (XtPointer)&val);
+
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(sticky, args, 1);
+ EnableCallback(sticky, (XtPointer)stickyForm, (XtPointer)(long)state);
+
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(mouse, args, 1);
+ EnableCallback(mouse, (XtPointer)mouseForm, (XtPointer)(long)state);
+ if (xkb_info->xkb->ctrls->mk_time_to_max > 10)
+ val = (float)((xkb_info->xkb->ctrls->mk_time_to_max * (40. / 10.))) /
+ (float)(MAX_MOUSE_TIME * 100);
+ else
+ val = 10.0 / (float)(MAX_MOUSE_TIME * 100);
+ ScaleJumpCallback(mouseTime->scroller, (XtPointer)mouseTime,
+ (XtPointer)&val);
+ tmp = mouseTime->value;
+ if (xkb_info->xkb->ctrls->mk_max_speed != 0)
+ val = (float)(xkb_info->xkb->ctrls->mk_max_speed / tmp - 10) /
+ (float)MAX_MOUSE_SPEED;
+ else
+ val = 10.0 / (float)MAX_MOUSE_SPEED;
+ ScaleJumpCallback(mouseSpeed->scroller, (XtPointer)mouseSpeed,
+ (XtPointer)&val);
+ if (xkb_info->xkb->ctrls->mk_delay > 10)
+ val = (float)(xkb_info->xkb->ctrls->mk_delay - 10) /
+ (float)(MAX_MOUSE_DELAY * 100);
+ else
+ val = 10.0 / (float)(MAX_MOUSE_DELAY * 100);
+ ScaleJumpCallback(mouseDelay->scroller, (XtPointer)mouseDelay,
+ (XtPointer)&val);
+
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(repeat, args, 1);
+ EnableCallback(repeat, (XtPointer)repeatForm, (XtPointer)(long)state);
+ if (xkb_info->xkb->ctrls->repeat_interval > 5)
+ val = (float)(xkb_info->xkb->ctrls->repeat_interval - 5) /
+ (float)(MAX_REPEAT_RATE * 1000);
+ else
+ val = 5.0 / (float)(MAX_REPEAT_RATE * 1000);
+ ScaleJumpCallback(repeatRate->scroller, (XtPointer)repeatRate,
+ (XtPointer)&val);
+ if (xkb_info->xkb->ctrls->repeat_delay > 5)
+ val = (float)(xkb_info->xkb->ctrls->repeat_delay - 5) /
+ (float)(MAX_REPEAT_DELAY * 1000);
+ else
+ val = 5.0 / (float)(MAX_REPEAT_DELAY * 1000);
+ ScaleJumpCallback(repeatDelay->scroller, (XtPointer)repeatDelay,
+ (XtPointer)&val);
+
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(slowToggle, args, 1);
+ EnableCallback(slowToggle, (XtPointer)slowForm, (XtPointer)(long)state);
+ if (xkb_info->xkb->ctrls->slow_keys_delay > 10)
+ val = (float)(xkb_info->xkb->ctrls->repeat_delay - 10) /
+ (float)(MAX_SLOW_TIME * 1000);
+ else
+ val = 10.0 / (float)(MAX_SLOW_TIME * 1000);
+ ScaleJumpCallback(slow->scroller, (XtPointer)slow, (XtPointer)&val);
+
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(bounceToggle, args, 1);
+ EnableCallback(bounceToggle, (XtPointer)bounceForm, (XtPointer)(long)state);
+ if (xkb_info->xkb->ctrls->debounce_delay > 10)
+ val = (float)(xkb_info->xkb->ctrls->debounce_delay - 10) /
+ (float)(MAX_BOUNCE_TIME * 1000);
+ else
+ val = 10.0 / (float)(MAX_BOUNCE_TIME * 1000);
+ ScaleJumpCallback(bounce->scroller, (XtPointer)bounce, (XtPointer)&val);
+
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(enable, args, 1);
+}
+
+void
+AccessXConfigureStart(void)
+{
+ AccessXInitialize();
+
+ XtMapWidget(accessx);
+}
+
+void
+AccessXConfigureEnd(void)
+{
+ XtUnmapWidget(accessx);
+}
+
+/*ARGSUSED*/
+static void
+EnableCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XtSetSensitive((Widget)user_data, (long)call_data);
+}
+
+/*ARGSUSED*/
+static void
+ScaleEnableCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Scale *scale = (Scale*)user_data;
+
+ XtSetSensitive(scale->label, (long)call_data);
+ XtSetSensitive(scale->number, (long)call_data);
+ XtSetSensitive(scale->scroller, (long)call_data);
+}
+
+static void
+ScaleJumpCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Scale *scale = (Scale*)user_data;
+ float percent = *(float *)call_data, timeout = percent * scale->max;
+ int x;
+ char str[8];
+ Arg args[1];
+
+ if (timeout >= scale->max - scale->min)
+ timeout = scale->max - scale->min;
+
+ if (scale->integer) {
+ int tm = timeout + scale->min;
+
+ tm -= tm % (int)scale->resolution;
+ XmuSnprintf(str, sizeof(str), "%i", tm);
+ scale->value = tm;
+ }
+ else {
+ long tm = (timeout + scale->min) * 1e+6;
+
+ tm -= tm % (long)(scale->resolution * 1e+6);
+ scale->value = (double)tm / 1e+6;
+ XmuSnprintf(str, sizeof(str), "%f", scale->value);
+ }
+
+ XtSetArg(args[0], XtNlabel, str);
+ XtSetValues(scale->number, args, 1);
+ x = w->core.x + w->core.border_width;
+ x += ((double)(w->core.width - scale->number->core.width) / scale->max) * timeout;
+ XtMoveWidget(scale->number, x, scale->number->core.y);
+ XawScrollbarSetThumb(w, timeout / (scale->max - scale->min),
+ scale->resolution / (scale->max - scale->min));
+}
+
+/*ARGSUSED*/
+static void
+ApplyCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[1];
+ Boolean state;
+
+ XkbGetControls(DPY, XkbAllControlsMask, xkb_info->xkb);
+
+ /* Enable AccessX */
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(enable, args, 1);
+ if (state) {
+ xkb_info->config.initial_ctrls |= XkbAccessXKeysMask;
+ xkb_info->xkb->ctrls->enabled_ctrls |= XkbAccessXKeysMask;
+ }
+ else {
+ xkb_info->config.initial_ctrls &= ~XkbAccessXKeysMask;
+ xkb_info->xkb->ctrls->enabled_ctrls &= ~XkbAccessXKeysMask;
+ }
+
+ /* Timeout */
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(timeoutToggle, args, 1);
+ if (state)
+ xkb_info->config.ax_timeout =
+ xkb_info->xkb->ctrls->ax_timeout = timeout->value * 60;
+ else
+ xkb_info->config.ax_timeout =
+ xkb_info->xkb->ctrls->ax_timeout = 65535;
+
+ /* Enable StickyKeys */
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(sticky, args, 1);
+ if (state) {
+ xkb_info->config.initial_ctrls |= XkbStickyKeysMask;
+ xkb_info->xkb->ctrls->enabled_ctrls |= XkbStickyKeysMask;
+ }
+ else {
+ xkb_info->config.initial_ctrls &= ~XkbStickyKeysMask;
+ xkb_info->xkb->ctrls->enabled_ctrls &= ~XkbStickyKeysMask;
+ }
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(stickyAuto, args, 1);
+ if (state) {
+ xkb_info->config.initial_opts &= ~XkbAX_TwoKeysMask;
+ xkb_info->config.initial_opts &= ~XkbAX_LatchToLockMask;
+ xkb_info->xkb->ctrls->ax_options &= ~XkbAX_TwoKeysMask;
+ xkb_info->xkb->ctrls->ax_options &= ~XkbAX_LatchToLockMask;
+ }
+ else {
+ xkb_info->config.initial_opts &= ~XkbAX_TwoKeysMask;
+ xkb_info->config.initial_opts |= XkbAX_LatchToLockMask;
+ xkb_info->xkb->ctrls->ax_options &= ~XkbAX_TwoKeysMask;
+ xkb_info->xkb->ctrls->ax_options |= XkbAX_LatchToLockMask;
+ }
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(stickyBeep, args, 1);
+ if (state) {
+ xkb_info->config.initial_opts |= XkbAX_StickyKeysFBMask;
+ xkb_info->xkb->ctrls->ax_options |= XkbAX_StickyKeysFBMask;
+ }
+ else {
+ xkb_info->config.initial_opts &= ~XkbAX_StickyKeysFBMask;
+ xkb_info->xkb->ctrls->ax_options &= ~XkbAX_StickyKeysFBMask;
+ }
+
+ /* Enable MouseKeys */
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(mouse, args, 1);
+ if (state) {
+ xkb_info->config.initial_ctrls |= XkbMouseKeysAccelMask;
+ xkb_info->xkb->ctrls->enabled_ctrls |= XkbMouseKeysMask |
+ XkbMouseKeysAccelMask;
+ xkb_info->config.mk_delay =
+ xkb_info->xkb->ctrls->mk_delay = mouseDelay->value * 100;
+ xkb_info->config.mk_interval =
+ xkb_info->xkb->ctrls->mk_interval = 40;
+ xkb_info->config.mk_time_to_max =
+ xkb_info->xkb->ctrls->mk_time_to_max =
+ (mouseTime->value * 1000) / xkb_info->xkb->ctrls->mk_interval;
+ xkb_info->config.mk_max_speed =
+ xkb_info->xkb->ctrls->mk_max_speed =
+ mouseSpeed->value * mouseTime->value;
+ xkb_info->config.mk_curve = xkb_info->xkb->ctrls->mk_curve = 0;
+ }
+ else {
+ xkb_info->config.initial_ctrls &= ~(XkbMouseKeysMask |
+ XkbMouseKeysAccelMask);
+ xkb_info->xkb->ctrls->enabled_ctrls &= ~(XkbMouseKeysMask |
+ XkbMouseKeysAccelMask);
+ }
+
+ /* Enable RepeatKeys */
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(repeat, args, 1);
+ if (state) {
+ xkb_info->config.initial_ctrls |= XkbRepeatKeysMask;
+ xkb_info->xkb->ctrls->enabled_ctrls |= XkbRepeatKeysMask;
+ xkb_info->config.repeat_interval =
+ xkb_info->xkb->ctrls->repeat_interval = repeatRate->value * 1000;
+ xkb_info->config.repeat_delay =
+ xkb_info->xkb->ctrls->repeat_delay = repeatDelay->value * 1000;
+ }
+ else {
+ xkb_info->config.initial_ctrls &= ~XkbRepeatKeysMask;
+ xkb_info->xkb->ctrls->enabled_ctrls &= ~XkbRepeatKeysMask;
+ }
+
+ /* Enable SlowKeys */
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(slowToggle, args, 1);
+ if (state) {
+ xkb_info->config.initial_ctrls |= XkbSlowKeysMask;
+ xkb_info->xkb->ctrls->enabled_ctrls |= XkbSlowKeysMask;
+ xkb_info->config.slow_keys_delay =
+ xkb_info->xkb->ctrls->slow_keys_delay = slow->value * 1000;
+ }
+ else {
+ xkb_info->config.initial_ctrls &= ~XkbSlowKeysMask;
+ xkb_info->xkb->ctrls->enabled_ctrls &= ~XkbSlowKeysMask;
+ }
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(slowPressed, args, 1);
+ if (state) {
+ xkb_info->config.initial_opts |= XkbAX_SKPressFBMask;
+ xkb_info->xkb->ctrls->ax_options |= XkbAX_SKPressFBMask;
+ }
+ else {
+ xkb_info->config.initial_opts &= ~XkbAX_SKPressFBMask;
+ xkb_info->xkb->ctrls->ax_options &= ~XkbAX_SKPressFBMask;
+ }
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(slowAccepted, args, 1);
+ if (state) {
+ xkb_info->config.initial_opts |= XkbAX_SKAcceptFBMask;
+ xkb_info->xkb->ctrls->ax_options |= XkbAX_SKAcceptFBMask;
+ }
+ else {
+ xkb_info->config.initial_opts &= ~XkbAX_SKAcceptFBMask;
+ xkb_info->xkb->ctrls->ax_options &= ~XkbAX_SKAcceptFBMask;
+ }
+
+ /* Enable BounceKeys */
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(bounceToggle, args, 1);
+ if (state) {
+ xkb_info->config.initial_ctrls |= XkbBounceKeysMask;
+ xkb_info->xkb->ctrls->enabled_ctrls |= XkbBounceKeysMask;
+ xkb_info->config.debounce_delay =
+ xkb_info->xkb->ctrls->debounce_delay = bounce->value * 1000;
+ }
+ else {
+ xkb_info->config.initial_ctrls &= ~XkbBounceKeysMask;
+ xkb_info->xkb->ctrls->enabled_ctrls &= ~XkbBounceKeysMask;
+ }
+
+ XkbSetControls(DPY, XkbAllControlsMask, xkb_info->xkb);
+ XSync(DPY, False);
+ (void)UpdateKeyboard(True);
+}
diff --git a/hw/xfree86/utils/xorgcfg/card-cfg.c b/hw/xfree86/utils/xorgcfg/card-cfg.c
new file mode 100644
index 000000000..a96797f1c
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/card-cfg.c
@@ -0,0 +1,434 @@
+/*
+ * 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/card-cfg.c,v 1.11 2001/11/01 19:08:58 paulo Exp $
+ */
+
+#include "xf86config.h"
+#include "mouse-cfg.h"
+#include "cards.h"
+#include "card-cfg.h"
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/List.h>
+#include <X11/Xaw/MenuButton.h>
+#include <X11/Xaw/SmeBSB.h>
+#include <X11/Xaw/SimpleMenu.h>
+#include <X11/Xaw/Viewport.h>
+#ifdef USE_MODULES
+#include "loader.h"
+#endif
+
+/*
+ * Prototypes
+ */
+static Bool CardConfigCheck(void);
+static void CardModelCallback(Widget, XtPointer, XtPointer);
+#ifdef USE_MODULES
+static void DriverCallback(Widget, XtPointer, XtPointer);
+#endif
+
+/*
+ * Initialization
+ */
+static CardsEntry *card_entry;
+static XF86ConfDevicePtr current_device;
+static Widget filter, list, driver, busid;
+static char **cards = NULL;
+static int ncards;
+#ifdef USE_MODULES
+static char *driver_str;
+#endif
+
+/*
+ * Implementation
+ */
+/*ARGSUSED*/
+XtPointer
+CardConfig(XtPointer config)
+{
+ XF86ConfDevicePtr card = (XF86ConfDevicePtr)config;
+/* XF86OptionPtr option;*/
+ char card_name[32];
+ Arg args[1];
+ char *bus, *drv_nam;
+
+ xf86info.cur_list = CARD;
+ XtSetSensitive(back, xf86info.lists[CARD].cur_function > 0);
+ XtSetSensitive(next, xf86info.lists[CARD].cur_function <
+ xf86info.lists[CARD].num_functions - 1);
+ (xf86info.lists[CARD].functions[xf86info.lists[CARD].cur_function])
+ (&xf86info);
+
+ card_entry = NULL;
+ current_device = card;
+ XawListUnhighlight(list);
+ XtSetArg(args[0], XtNstring, "");
+ XtSetValues(filter, args, 1);
+
+ if (card != NULL) {
+ if (card->dev_card != NULL) {
+ int i;
+
+ for (i = 0; i < ncards; i++) {
+ if (strcasecmp(cards[i], card->dev_card) == 0) {
+ card_entry = LookupCard(cards[i]);
+ XawListHighlight(list, i);
+ XtSetArg(args[0], XtNstring, cards[i]);
+ XtSetValues(filter, args, 1);
+ break;
+ }
+ }
+ }
+ XtSetArg(args[0], XtNstring, card->dev_identifier);
+ XtSetValues(ident_widget, args, 1);
+ XtSetArg(args[0], XtNstring, card->dev_busid);
+ XtSetValues(busid, args, 1);
+#ifdef USE_MODULES
+ if (!nomodules)
+ XtSetArg(args[0], XtNlabel, driver_str = XtNewString(card->dev_driver));
+ else
+#endif
+ XtSetArg(args[0], XtNstring, card->dev_driver);
+ XtSetValues(driver, args, 1);
+ }
+ else {
+ XF86ConfDevicePtr device = XF86Config->conf_device_lst;
+ int ndevices = 0;
+
+ while (device != NULL) {
+ ++ndevices;
+ device = (XF86ConfDevicePtr)(device->list.next);
+ }
+ do {
+ XmuSnprintf(card_name, sizeof(card_name), "Card%d", ndevices);
+ ++ndevices;
+ } while (xf86findDevice(card_name,
+ XF86Config->conf_device_lst));
+
+ XtSetArg(args[0], XtNstring, card_name);
+ XtSetValues(ident_widget, args, 1);
+ XtSetArg(args[0], XtNstring, "");
+ XtSetValues(busid, args, 1);
+#ifdef USE_MODULES
+ if (!nomodules)
+ XtSetArg(args[0], XtNlabel, driver_str = XtNewString("vga"));
+ else
+#endif
+ XtSetArg(args[0], XtNstring, "vga");
+ XtSetValues(driver, args, 1);
+ }
+
+ if (ConfigLoop(CardConfigCheck) == True) {
+ if (card_entry != NULL && card_entry->driver == NULL) {
+ fprintf(stderr, "No driver field in Cards database.\n"
+ "Please make sure you have the correct files installed.\n");
+ exit(1);
+ }
+ if (card == NULL) {
+ card = (XF86ConfDevicePtr)XtCalloc(1, sizeof(XF86ConfDeviceRec));
+ card->dev_identifier = XtNewString(ident_string);
+ if (card_entry) {
+ card->dev_driver = XtNewString(card_entry->driver);
+ card->dev_card = XtNewString(card_entry->name);
+ if (card_entry->chipset)
+ card->dev_chipset = XtNewString(card_entry->chipset);
+ if (card_entry->ramdac)
+ card->dev_ramdac = XtNewString(card_entry->ramdac);
+ if (card_entry->clockchip)
+ card->dev_clockchip = XtNewString(card_entry->clockchip);
+ }
+ /* else will fallback to "vga" */
+ }
+ else if (card_entry != NULL) {
+ XtFree(card->dev_driver);
+ card->dev_driver = XtNewString(card_entry->driver);
+ if (card_entry->chipset) {
+ XtFree(card->dev_chipset);
+ card->dev_chipset = XtNewString(card_entry->chipset);
+ }
+ if (card_entry->ramdac) {
+ XtFree(card->dev_ramdac);
+ card->dev_ramdac = XtNewString(card_entry->ramdac);
+ }
+ if (card_entry->clockchip) {
+ XtFree(card->dev_clockchip);
+ card->dev_clockchip = XtNewString(card_entry->clockchip);
+ }
+ }
+ if (strcasecmp(card->dev_identifier, ident_string))
+ xf86renameDevice(XF86Config, card, ident_string);
+ XtSetArg(args[0], XtNstring, &bus);
+ XtGetValues(busid, args, 1);
+ XtFree(card->dev_busid);
+ card->dev_busid = XtNewString(bus);
+
+#ifdef USE_MODULES
+ if (!nomodules)
+ drv_nam = driver_str;
+ else
+#endif
+ {
+ XtSetArg(args[0], XtNstring, &drv_nam);
+ XtGetValues(driver, args, 1);
+ }
+
+ XtFree(card->dev_driver);
+ card->dev_driver = XtNewString(drv_nam);
+
+#ifdef USE_MODULES
+ if (!nomodules)
+ XtFree(driver_str);
+#endif
+
+ return ((XtPointer)card);
+ }
+#ifdef USE_MODULES
+ if (!nomodules)
+ XtFree(driver_str);
+#endif
+
+ return (NULL);
+}
+
+static Bool
+CardConfigCheck(void)
+{
+ XF86ConfDevicePtr device = XF86Config->conf_device_lst;
+ char *drv_nam;
+
+#ifdef USE_MODULES
+ if (!nomodules)
+ drv_nam = driver_str;
+ else
+#endif
+ {
+ Arg args[1];
+
+ XtSetArg(args[0], XtNstring, &drv_nam);
+ XtGetValues(driver, args, 1);
+ }
+
+ if (ident_string == NULL || strlen(ident_string) == 0 ||
+#if 0
+ /* not all available cards are in the Cards database */
+ (current_device == NULL && card_entry == NULL) ||
+#endif
+ drv_nam == NULL || *drv_nam == '\0')
+ return (False);
+
+ while (device != NULL) {
+ if (device != current_device &&
+ strcasecmp(ident_string, device->dev_identifier) == 0)
+ return (False);
+ device = (XF86ConfDevicePtr)(device->list.next);
+ }
+
+ return (True);
+}
+
+static void
+CardModelCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[1];
+ XawListReturnStruct *info = (XawListReturnStruct *)call_data;
+ char tip[4096];
+ int len;
+
+ XtSetArg(args[0], XtNstring, info->string);
+ XtSetValues(filter, args, 1);
+ card_entry = LookupCard(info->string);
+
+ if (card_entry == NULL)
+ return;
+
+ len = XmuSnprintf(tip, sizeof(tip), "Name: %s\n", card_entry->name);
+ if (card_entry->flags & F_UNSUPPORTED)
+ len += XmuSnprintf(tip + len, sizeof(tip) - len,
+ "**THIS CARD IS UNSUPPORTED**\n");
+ if (card_entry->chipset != NULL)
+ len += XmuSnprintf(tip + len, sizeof(tip) - len,
+ "Chipset: %s\n", card_entry->chipset);
+ if (card_entry->driver != NULL) {
+#ifdef USE_MODULES
+ if (!nomodules) {
+ XtFree(driver_str);
+ driver_str = XtNewString(card_entry->driver);
+ XtVaSetValues(driver, XtNlabel, driver_str, NULL, 0);
+ }
+#endif
+ len += XmuSnprintf(tip + len, sizeof(tip) - len,
+ "Driver: %s\n", card_entry->driver);
+ }
+ if (card_entry->ramdac != NULL)
+ len += XmuSnprintf(tip + len, sizeof(tip),
+ "Ramdac: %s\n", card_entry->ramdac);
+ if (card_entry->clockchip != NULL)
+ len += XmuSnprintf(tip + len, sizeof(tip) - len,
+ "Clockchip: %s\n", card_entry->clockchip);
+ if (card_entry->dacspeed != NULL)
+ len += XmuSnprintf(tip + len, sizeof(tip) - len,
+ "Dacspeed: %s\n", card_entry->dacspeed);
+ if (card_entry->lines != NULL)
+ len += XmuSnprintf(tip + len, sizeof(tip) - len,
+ "\n%s\n", card_entry->lines);
+
+#ifndef USE_MODULES
+ XtSetArg(args[0], XtNstring,
+ card_entry->driver ? card_entry->driver : "vga");
+ XtSetValues(driver, args, 1);
+#endif
+
+ XtSetArg(args[0], XtNtip, tip);
+ XtSetValues(filter, args, 1);
+}
+
+/*ARGSUSED*/
+void
+CardFilterAction(Widget w, XEvent *ev, String *params, Cardinal *num_params)
+{
+ char **cards, *pattern, **old_cards;
+ int ncards, old_ncards;
+ Arg args[2];
+
+ XtSetArg(args[0], XtNstring, &pattern);
+ XtGetValues(w, args, 1);
+
+ XtSetArg(args[0], XtNlist, &old_cards);
+ XtSetArg(args[1], XtNnumberStrings, &old_ncards);
+ XtGetValues(list, args, 2);
+
+ cards = FilterCardNames(pattern, &ncards);
+
+ if (ncards == 0) {
+ cards = (char**)XtMalloc(sizeof(char*));
+ cards[0] = XtNewString("");
+ ncards = 1;
+ }
+
+ XtSetArg(args[0], XtNlist, cards);
+ XtSetArg(args[1], XtNnumberStrings, ncards);
+ XtSetValues(list, args, 2);
+
+ if (old_ncards > 1 || (XtName(list) != old_cards[0])) {
+ while (--old_ncards > -1)
+ XtFree(old_cards[old_ncards]);
+ XtFree((char*)old_cards);
+ }
+
+ /* force relayout */
+ XtUnmanageChild(list);
+ XtManageChild(list);
+}
+
+#ifdef USE_MODULES
+/*ARGSUSED*/
+static void
+DriverCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[1];
+
+ XtFree(driver_str);
+ driver_str = XtNewString(XtName(w));
+ XtSetArg(args[0], XtNlabel, driver_str);
+ XtSetValues(driver, args, 1);
+}
+#endif
+
+void
+CardModel(XF86SetupInfo *info)
+{
+ static int first = 1;
+ static Widget model;
+
+ if (first) {
+ Widget label, viewport;
+
+ first = 0;
+
+ cards = GetCardNames(&ncards);
+
+ model = XtCreateWidget("cardModel", formWidgetClass,
+ configp, NULL, 0);
+ label = XtCreateManagedWidget("label", labelWidgetClass,
+ model, NULL, 0);
+ filter = XtVaCreateManagedWidget("filter", asciiTextWidgetClass,
+ model,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ viewport = XtCreateManagedWidget("viewport", viewportWidgetClass,
+ model, NULL, 0);
+ list = XtVaCreateManagedWidget("list", listWidgetClass,
+ viewport,
+ XtNlist, cards,
+ XtNnumberStrings, ncards,
+ NULL, 0);
+ XtAddCallback(list, XtNcallback, CardModelCallback,
+ (XtPointer)info);
+ XtCreateManagedWidget("driverL", labelWidgetClass, model, NULL, 0);
+#ifdef USE_MODULES
+ if (!nomodules) {
+ driver = XtVaCreateManagedWidget("driver", menuButtonWidgetClass,
+ model,
+ XtNmenuName, "driverM",
+ NULL, 0);
+ {
+ Widget menu, sme;
+ xf86cfgModuleOptions *opts = module_options;
+
+ menu = XtCreatePopupShell("driverM", simpleMenuWidgetClass,
+ driver, NULL, 0);
+ while (opts) {
+ if (opts->type == VideoModule) {
+ sme = XtCreateManagedWidget(opts->name, smeBSBObjectClass,
+ menu, NULL, 0);
+ XtAddCallback(sme, XtNcallback, DriverCallback, NULL);
+ }
+ opts = opts->next;
+ }
+ }
+ }
+ else
+#endif
+ driver = XtVaCreateManagedWidget("driver", asciiTextWidgetClass,
+ model,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+
+ XtCreateManagedWidget("busidL", labelWidgetClass, model, NULL, 0);
+ busid = XtVaCreateManagedWidget("busid", asciiTextWidgetClass,
+ model,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+
+ XtRealizeWidget(model);
+ }
+ XtChangeManagedSet(&current, 1, NULL, NULL, &model, 1);
+ current = model;
+}
diff --git a/hw/xfree86/utils/xorgcfg/card-cfg.h b/hw/xfree86/utils/xorgcfg/card-cfg.h
new file mode 100644
index 000000000..14411440d
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/card-cfg.h
@@ -0,0 +1,44 @@
+/*
+ * 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/card-cfg.h,v 1.1 2000/04/04 22:36:57 dawes Exp $
+ */
+
+#include "config.h"
+
+#ifndef _xf86cfg_card_h
+#define _xf86cfg_card_h
+
+/*
+ * Prototypes
+ */
+XtPointer CardConfig(XtPointer);
+void CardModel(XF86SetupInfo*);
+void CardFilterAction(Widget, XEvent*, String*, Cardinal*);
+
+#endif /* _xf86cfg_card_h */
diff --git a/hw/xfree86/utils/xorgcfg/card.xbm b/hw/xfree86/utils/xorgcfg/card.xbm
new file mode 100644
index 000000000..b3cbba322
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/card.xbm
@@ -0,0 +1,59 @@
+/*
+ * 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/card.xbm,v 1.1 2000/04/04 22:36:57 dawes Exp $
+ */
+#define card_width 50
+#define card_height 44
+static unsigned char card_bits[] = {
+ 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfd, 0xff, 0xff, 0xff, 0x07,
+ 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x80, 0x07, 0x00, 0x00,
+ 0x00, 0x1c, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x80, 0x01,
+ 0x00, 0x00, 0xf8, 0x19, 0x00, 0x80, 0xf9, 0x00, 0x00, 0xf8, 0x19, 0x00,
+ 0x80, 0xf9, 0xf8, 0x7f, 0x98, 0x19, 0x00, 0x80, 0x01, 0xf8, 0x7f, 0x98,
+ 0x19, 0x00, 0x80, 0x01, 0x18, 0x60, 0xf8, 0x19, 0x00, 0x80, 0xf9, 0x18,
+ 0x60, 0xf8, 0x19, 0x00, 0x80, 0xf9, 0x18, 0x60, 0x00, 0x18, 0x00, 0x80,
+ 0x01, 0x18, 0x60, 0xf8, 0x19, 0x00, 0x80, 0x01, 0x18, 0x60, 0xf8, 0x19,
+ 0x00, 0x80, 0xf9, 0x18, 0x60, 0x98, 0x19, 0x00, 0x80, 0xf9, 0x18, 0x60,
+ 0x98, 0x19, 0x00, 0x80, 0x01, 0x18, 0x60, 0xf8, 0x19, 0x00, 0x80, 0x01,
+ 0xf8, 0x7f, 0xf8, 0x19, 0x00, 0x80, 0xf9, 0xf8, 0x7f, 0x00, 0x18, 0x00,
+ 0x80, 0xf9, 0x00, 0x00, 0xf8, 0x19, 0x00, 0x80, 0x01, 0x00, 0x00, 0xf8,
+ 0x19, 0x00, 0x80, 0x01, 0x30, 0x33, 0x98, 0x19, 0x00, 0x80, 0xf9, 0x30,
+ 0x33, 0x98, 0x19, 0x00, 0x80, 0xf9, 0x30, 0x33, 0xf8, 0x19, 0x00, 0x80,
+ 0x01, 0x30, 0x33, 0xf8, 0x19, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x18,
+ 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x80, 0xff, 0x07, 0x00,
+ 0x80, 0x0f, 0x00, 0x80, 0xfd, 0x0f, 0x00, 0xc0, 0x07, 0x00, 0x80, 0x01,
+ 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x80, 0x01, 0xcc, 0xcc, 0xcc, 0x00, 0x00,
+ 0x80, 0x01, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x80, 0x01, 0xcc, 0xcc, 0xcc,
+ 0x00, 0x00, 0x80, 0x01, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x80, 0x01, 0xf8,
+ 0xff, 0x7f, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
diff --git a/hw/xfree86/utils/xorgcfg/card.xpm b/hw/xfree86/utils/xorgcfg/card.xpm
new file mode 100644
index 000000000..d68257469
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/card.xpm
@@ -0,0 +1,81 @@
+/* XPM */
+/*
+ * 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/card.xpm,v 1.1 2000/04/04 22:36:57 dawes Exp $
+ */
+static char * card_xpm[] = {
+"41 40 8 1",
+" c none",
+"A c #B6DABAEAB6DA",
+"X c #0000AAAA0000",
+"o c #000071C60000",
+"O c #000041030000",
+"+ c #618561856185",
+"@ c #186118611861",
+"# c #CF3CA2892081",
+"AAA ",
+" A ",
+" A ",
+" A ",
+" A ",
+" A ",
+" A ",
+" AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
+" AooooooooooooooooooooooooooooooooooooO",
+" AooooooooooooooooooooooooooooooooooooO",
+" AooooooooooooooooooooooooooooooooooooO",
+" AooooooooooooooooooooooooOOOOOOOOOOOOO",
+" AooooooooooooooooooAoAoAoAooAAAAAAA+oO",
+" AooooooooooooooooooAoAoAoAooA++++++@oO",
+" AooooooooooooooooooAoAoAoAooA+oooo+@oO",
+" AoooooooooooooooooooooooooooA+AAAA+@oO",
+" AoooooooooooooooooooooooooooA+oooo+@oO",
+" AoooooooooooooooooooooooooooA++++++@oO",
+" Aooooooooooooooooooooooooooo+@@@@@@@oO",
+" AooooooooooooooooooooooooooooooooooooO",
+" AoooooooooooooooooooooooooooAAAAAAA+oO",
+" +AoooooooooooooooooAAAAAAAA@oA++++++@oO",
+" AoooooooooooooooooA+++++++@oA+oooo+@oO",
+" AoooooooooooooooooA+++++++@oA+AAAA+@oO",
+" ++AoooooooooooooooooA+++++++@oA+oooo+@oO",
+" ++AoooooooooooooooooA+++++++@oA++++++@oO",
+" ++Aooooooooooooooooo@@@@@@@@@o+@@@@@@@oO",
+" ++AooooooooooooooooooooooooooooooooooooO",
+" AooooooooooooooooooooooooooooooooooooO",
+" AooooooooooooooooooooooooooooooooooooO",
+" +AooooooooooooooooooooooooooooooooooooO",
+" AooooooooooooooooooooooooooooooooooooO",
+" AoooOOOOooooooooooooooooooooOoooooOOO ",
+" AooO X#o#o#o#o#o#o#o#o#oO X#o#O ",
+" AOO X#o#o#o#o#o#o#o#o#oO X#o#O ",
+" A X#o#o#o#o#o#o#o#o#oO X#o#O ",
+" A X#o#o#o#o#o#o#o#o#oO X#o#O ",
+" A OOOOOOOOOOOOOOOOOO OOO ",
+" A ",
+" A "};
diff --git a/hw/xfree86/utils/xorgcfg/cards.c b/hw/xfree86/utils/xorgcfg/cards.c
new file mode 100644
index 000000000..d5805fa98
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/cards.c
@@ -0,0 +1,693 @@
+/*
+ * 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/cards.c,v 1.15 2003/02/15 05:37:58 paulo Exp $
+ */
+
+#define CARDS_PRIVATE
+#include "cards.h"
+
+#undef SERVER /* defined in config.h, but of no use here */
+
+/* return values from ReadCardsLine. */
+#define ERROR -3
+#define UNKNOWN -2
+#define END -1
+#define NOTUSEFUL 0
+#define NAME 1
+#define CHIPSET 2
+#define SERVER 3
+#define DRIVER 4
+#define RAMDAC 5
+#define CLOCKCHIP 6
+#define DACSPEED 7
+#define NOCLOCKPROBE 8
+#define UNSUPPORTED 9
+#define SEE 10
+#define LINE 11
+
+/*
+ * Prototypes
+ */
+static int ReadCardsLine(FILE*, char*); /* must have 256 bytes */
+static int CompareCards(_Xconst void *left, _Xconst void *right);
+static int BCompareCards(_Xconst void *left, _Xconst void *right);
+static void DoReadCardsDatabase(void);
+static char **DoFilterCardNames(char *pattern, int *result);
+
+#ifdef USE_MODULES
+
+typedef struct {
+ int ivendor;
+ unsigned short vendor;
+ unsigned short valid_vendor;
+ char *chipsets;
+ int num_chipsets;
+} chipset_check;
+#endif
+
+/*
+ * Initialization
+ */
+static int linenum = 0;
+static char *Cards = "lib/X11/Cards";
+CardsEntry **CardsDB;
+int NumCardsEntry;
+
+/*
+ * Implementation
+ */
+#ifdef USE_MODULES
+const pciVendorInfo *xf86PCIVendorInfo;
+#endif
+
+#ifdef USE_MODULES
+void
+InitializePciInfo(void)
+{
+ xf86PCIVendorInfo = pciVendorInfoList;
+}
+
+void
+CheckChipsets(xf86cfgModuleOptions *opts, int *err)
+{
+ int i, j, ichk, ivnd = 0, vendor = -1, device;
+ const pciDeviceInfo **pDev;
+ SymTabPtr chips = opts->chipsets;
+ chipset_check *check = NULL;
+ int num_check = 0;
+
+ if (!chips) {
+ CheckMsg(CHECKER_NO_CHIPSETS, "WARNING No chipsets specified.\n");
+ ++*err;
+ return;
+ }
+
+ while (chips->name) {
+ device = chips->token & 0xffff;
+ vendor = (chips->token & 0xffff0000) >> 16;
+ if (vendor == 0)
+ vendor = opts->vendor;
+
+ for (ichk = 0; ichk < num_check; ichk++)
+ if (check[ichk].vendor == vendor)
+ break;
+ if (ichk >= num_check) {
+ check = (chipset_check*)
+ XtRealloc((XtPointer)check,
+ sizeof(chipset_check) * (num_check + 1));
+ check[num_check].vendor = vendor;
+ memset(&check[num_check], 0, sizeof(chipset_check));
+ ++num_check;
+ }
+
+ /* Search for vendor in xf86PCIVendorInfo */
+ if (xf86PCIVendorInfo) {
+ for (ivnd = 0; xf86PCIVendorInfo[ivnd].VendorID; ivnd++)
+ if (vendor == xf86PCIVendorInfo[ivnd].VendorID)
+ break;
+ }
+ if (xf86PCIVendorInfo && xf86PCIVendorInfo[ivnd].VendorID) {
+ check[ichk].valid_vendor = 1;
+ check[ichk].ivendor = ivnd;
+ }
+ else {
+ CheckMsg(CHECKER_CANNOT_VERIFY_CHIPSET,
+ "WARNING Cannot verify chipset \"%s\" (0x%x)\n",
+ chips->name, device);
+ ++*err;
+ ++chips;
+ continue;
+ }
+
+ if (xf86PCIVendorInfo &&
+ (pDev = xf86PCIVendorInfo[ivnd].Device) != NULL) {
+ if (check[ichk].chipsets == NULL) {
+ for (j = 0; pDev[j]; j++)
+ ;
+ check[ichk].chipsets = (char*)XtCalloc(1, j);
+ }
+ for (j = 0; pDev[j]; j++) {
+ if (device == pDev[j]->DeviceID) {
+ if (strcmp(chips->name, pDev[j]->DeviceName)) {
+ CheckMsg(CHECKER_NOMATCH_CHIPSET_STRINGS,
+ "WARNING chipset strings don't match: \"%s\" \"%s\" (0x%x)\n",
+ chips->name, xf86PCIVendorInfo[ivnd].Device[j]->DeviceName,
+ device);
+ ++*err;
+ }
+ break;
+ }
+ }
+ if (!pDev[j]) {
+ CheckMsg(CHECKER_CHIPSET_NOT_LISTED,
+ "WARNING chipset \"%s\" (0x%x) not in list.\n", chips->name, device);
+ ++*err;
+ }
+ else
+ check[ichk].chipsets[j] = 1;
+ }
+ ++chips;
+ }
+
+ for (i = 0; i < num_check; i++) {
+ if (!check[i].valid_vendor) {
+ CheckMsg(CHECKER_CHIPSET_NO_VENDOR,
+ "WARNING No such vendor 0x%x\n", vendor);
+ ++*err;
+ }
+ for (j = 0; j < check[i].num_chipsets; j++) {
+ if (xf86PCIVendorInfo && !check[i].chipsets[j]) {
+ CheckMsg(CHECKER_CHIPSET_NOT_SUPPORTED,
+ "NOTICE chipset \"%s\" (0x%x) not listed as supported.\n",
+ xf86PCIVendorInfo[check[i].ivendor].Device[j]->DeviceName,
+ xf86PCIVendorInfo[check[i].ivendor].Device[j]->DeviceID);
+ }
+ }
+ XtFree(check[i].chipsets);
+ }
+
+ XtFree((XtPointer)check);
+}
+#endif
+
+void
+ReadCardsDatabase(void)
+{
+#ifdef USE_MODULES
+ if (!nomodules) {
+ int i, j, ivendor, idevice;
+ char name[256];
+ _Xconst char *vendor, *device;
+ CardsEntry *entry = NULL, *tmp;
+ xf86cfgModuleOptions *opts = module_options;
+ const pciDeviceInfo **pDev;
+
+ /* Only list cards that have a driver installed */
+ while (opts) {
+ if (opts->chipsets) {
+ SymTabPtr chips = opts->chipsets;
+
+ while (chips->name) {
+ vendor = opts->name;
+ device = chips->name;
+ ivendor = (chips->token & 0xffff0000) >> 16;
+ idevice = chips->token & 0xffff0;
+ if (ivendor == 0)
+ ivendor = opts->vendor;
+
+ if (xf86PCIVendorInfo) {
+ for (i = 0; xf86PCIVendorInfo[i].VendorName; i++)
+ if (ivendor == xf86PCIVendorInfo[i].VendorID) {
+ vendor = xf86PCIVendorInfo[i].VendorName;
+ break;
+ }
+ if (xf86PCIVendorInfo[i].VendorName) {
+ if ((pDev = xf86PCIVendorInfo[i].Device)) {
+ for (j = 0; pDev[j]; j++)
+ if (idevice == pDev[j]->DeviceID) {
+ device = pDev[j]->DeviceName;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Since frequently there is more than one driver for a
+ * single vendor, it is required to avoid duplicates.
+ */
+ XmuSnprintf(name, sizeof(name), "%s %s", vendor, device);
+ tmp = LookupCard(name);
+
+ if (tmp == NULL || strcmp(tmp->chipset, chips->name) ||
+ strcmp(tmp->driver, opts->name)) {
+ entry = (CardsEntry*)XtCalloc(1, sizeof(CardsEntry));
+ if (NumCardsEntry % 16 == 0) {
+ CardsDB = (CardsEntry**)XtRealloc((XtPointer)CardsDB,
+ sizeof(CardsEntry*) * (NumCardsEntry + 16));
+ }
+ CardsDB[NumCardsEntry++] = entry;
+ entry->name = XtNewString(name);
+
+ /* XXX no private copy of strings */
+ entry->chipset = (char*)chips->name;
+ entry->driver = opts->name;
+
+ /* better than linear searchs to find duplicates */
+ qsort(CardsDB, NumCardsEntry, sizeof(CardsEntry*),
+ CompareCards);
+ }
+ ++chips;
+ }
+ }
+ opts = opts->next;
+ }
+
+ /* fix entries with the same name */
+ for (i = 0; i < NumCardsEntry - 2;) {
+ for (j = i + 1; j < NumCardsEntry - 1 &&
+ strcmp(CardsDB[i]->name, CardsDB[j]->name) == 0; j++)
+ ;
+
+ if (i + 1 != j) {
+ while (i < j) {
+ char *str;
+
+ if (strcmp(CardsDB[i]->chipset, CardsDB[j]->chipset))
+ str = CardsDB[i]->chipset;
+ else
+ str = CardsDB[i]->driver;
+
+ XmuSnprintf(name, sizeof(name), "%s (%s)",
+ CardsDB[i]->name, str);
+ XtFree(CardsDB[i]->name);
+ CardsDB[i]->name = XtNewString(name);
+
+ ++i;
+ }
+ }
+ else
+ ++i;
+ }
+
+ /* make sure data is valid to bsearch in */
+ qsort(CardsDB, NumCardsEntry, sizeof(CardsEntry*), CompareCards);
+ }
+ else
+#endif
+ DoReadCardsDatabase();
+}
+
+static void
+DoReadCardsDatabase(void)
+{
+ char buffer[256];
+ FILE *fp = fopen(Cards, "r");
+ int i, result;
+ CardsEntry *entry = NULL;
+ static char *CardsError = "Error reading Cards database, at line %d (%s).\n";
+
+ if (fp == NULL) {
+ fprintf(stderr, "Cannot open Cards database.\n");
+ exit(1);
+ }
+
+ while ((result = ReadCardsLine(fp, buffer)) != END) {
+ switch (result) {
+ case ERROR:
+ fprintf(stderr, CardsError, linenum, buffer);
+ break;
+ case UNKNOWN:
+ fprintf(stderr,
+ "Unknown field type in Cards database, at line %d (%s).\n",
+ linenum, buffer);
+ break;
+ case NAME:
+ entry = calloc(1, sizeof(CardsEntry));
+ if (NumCardsEntry % 16 == 0) {
+ CardsDB = realloc(CardsDB, sizeof(CardsEntry*) *
+ (NumCardsEntry + 16));
+ if (CardsDB == NULL) {
+ fprintf(stderr, "Out of memory reading Cards database.\n");
+ exit(1);
+ }
+ }
+ CardsDB[NumCardsEntry++] = entry;
+ entry->name = strdup(buffer);
+ break;
+ case CHIPSET:
+ if (entry == NULL || entry->chipset != NULL) {
+ fprintf(stderr, CardsError, linenum, buffer);
+ }
+#if 0
+ else
+ entry->chipset = strdup(buffer);
+#endif
+ break;
+ case SERVER:
+ if (entry == NULL || entry->server != NULL) {
+ fprintf(stderr, CardsError, linenum, buffer);
+ }
+ else
+ entry->server = strdup(buffer);
+ break;
+ case DRIVER:
+ if (entry == NULL || entry->driver != NULL) {
+ fprintf(stderr, CardsError, linenum, buffer);
+ }
+ else
+ entry->driver = strdup(buffer);
+ break;
+ case RAMDAC:
+ if (entry == NULL || entry->ramdac != NULL) {
+ fprintf(stderr, CardsError, linenum, buffer);
+ }
+ else
+ entry->ramdac = strdup(buffer);
+ break;
+ case CLOCKCHIP:
+ if (entry == NULL || entry->clockchip != NULL) {
+ fprintf(stderr, CardsError, linenum, buffer);
+ }
+ else
+ entry->clockchip = strdup(buffer);
+ break;
+ case DACSPEED:
+ if (entry == NULL || entry->dacspeed != NULL) {
+ fprintf(stderr, CardsError, linenum, buffer);
+ }
+ else
+ entry->dacspeed = strdup(buffer);
+ break;
+ case NOCLOCKPROBE:
+ if (entry == NULL) {
+ fprintf(stderr, CardsError, linenum, buffer);
+ }
+ else
+ entry->flags |= F_NOCLOCKPROBE;
+ break;
+ case UNSUPPORTED:
+ if (entry == NULL) {
+ fprintf(stderr, CardsError, linenum, buffer);
+ }
+ else
+ entry->flags |= F_UNSUPPORTED;
+ break;
+ case SEE:
+ if (entry == NULL || entry->see != NULL) {
+ fprintf(stderr, CardsError, linenum, buffer);
+ }
+ else
+ entry->see = strdup(buffer);
+ break;
+ case LINE:
+ if (entry == NULL) {
+ fprintf(stderr, CardsError, linenum, buffer);
+ }
+ else if (entry->lines == NULL)
+ entry->lines = strdup(buffer);
+ else {
+ char *str = malloc(strlen(entry->lines) + strlen(buffer) + 2);
+
+ sprintf(str, "%s\n%s", entry->lines, buffer);
+ free(entry->lines);
+ entry->lines = str;
+ }
+ break;
+ }
+ }
+
+ fclose(fp);
+
+ qsort(CardsDB, NumCardsEntry, sizeof(CardsEntry*), CompareCards);
+
+#ifdef DEBUG
+ for (i = 0; i < NumCardsEntry - 1; i++) {
+ if (strcmp(CardsDB[i]->name, CardsDB[i+1]->name) == 0)
+ fprintf(stderr, "Duplicate entry in Cards database: (%s).\n",
+ CardsDB[i]->name);
+ }
+#endif
+
+ for (i = 0; i < NumCardsEntry - 1; i++) {
+ if (CardsDB[i]->see != NULL) {
+ if ((entry = LookupCard(CardsDB[i]->see)) == NULL) {
+ fprintf(stderr, "Cannot find card '%s' for filling defaults.\n",
+ CardsDB[i]->see);
+ continue;
+ }
+ if (CardsDB[i]->chipset == NULL && entry->chipset != NULL)
+ CardsDB[i]->chipset = strdup(entry->chipset);
+ if (CardsDB[i]->server == NULL && entry->server != NULL)
+ CardsDB[i]->server = strdup(entry->server);
+ if (CardsDB[i]->driver == NULL && entry->driver != NULL)
+ CardsDB[i]->driver = strdup(entry->driver);
+ if (CardsDB[i]->ramdac == NULL && entry->ramdac != NULL)
+ CardsDB[i]->ramdac = strdup(entry->ramdac);
+ if (CardsDB[i]->clockchip == NULL && entry->clockchip != NULL)
+ CardsDB[i]->clockchip = strdup(entry->clockchip);
+ if (CardsDB[i]->dacspeed == NULL && entry->dacspeed != NULL)
+ CardsDB[i]->dacspeed = strdup(entry->dacspeed);
+ if (CardsDB[i]->flags & F_NOCLOCKPROBE)
+ CardsDB[i]->flags |= F_NOCLOCKPROBE;
+ if (CardsDB[i]->flags & F_UNSUPPORTED)
+ CardsDB[i]->flags |= F_UNSUPPORTED;
+ if (entry->lines != NULL) {
+ if (CardsDB[i]->lines == NULL)
+ CardsDB[i]->lines = strdup(entry->lines);
+ else {
+ char *str = malloc(strlen(entry->lines) +
+ strlen(CardsDB[i]->lines) + 2);
+
+ sprintf(str, "%s\n%s", CardsDB[i]->lines, entry->lines);
+ free(CardsDB[i]->lines);
+ CardsDB[i]->lines = str;
+ }
+ }
+ if (entry->see != NULL) {
+#ifdef DEBUG
+ fprintf(stderr, "Nested SEE entry: %s -> %s -> %s\n",
+ CardsDB[i]->name, CardsDB[i]->see, entry->see);
+#endif
+ CardsDB[i]->see = strdup(entry->see);
+ --i;
+ continue;
+ }
+ free(CardsDB[i]->see);
+ CardsDB[i]->see = NULL;
+ }
+ }
+}
+
+CardsEntry *
+LookupCard(char *name)
+{
+ CardsEntry **ptr;
+
+ ptr = (CardsEntry**)bsearch(name, CardsDB, NumCardsEntry,
+ sizeof(CardsEntry*), BCompareCards);
+
+ return (ptr != NULL ? *ptr : NULL);
+}
+
+char **
+GetCardNames(int *result)
+{
+ char **cards = NULL;
+ int ncards;
+
+ for (ncards = 0; ncards < NumCardsEntry; ncards++) {
+ if (ncards % 16 == 0) {
+ if ((cards = (char**)realloc(cards, sizeof(char*) *
+ (ncards + 16))) == NULL) {
+ fprintf(stderr, "Out of memory.\n");
+ exit(1);
+ }
+ }
+ cards[ncards] = strdup(CardsDB[ncards]->name);
+ }
+
+ *result = ncards;
+
+ return (cards);
+}
+
+char **
+FilterCardNames(char *pattern, int *result)
+{
+#ifdef USE_MODULES
+ if (!nomodules) {
+ char **cards = NULL;
+ int i, ncards = 0;
+
+ for (i = 0; i < NumCardsEntry; i++) {
+ if (strstr(CardsDB[i]->name, pattern) == NULL)
+ continue;
+ if (ncards % 16 == 0) {
+ if ((cards = (char**)realloc(cards, sizeof(char*) *
+ (ncards + 16))) == NULL) {
+ fprintf(stderr, "Out of memory.\n");
+ exit(1);
+ }
+ }
+ cards[ncards] = strdup(CardsDB[i]->name);
+ ++ncards;
+ }
+
+ *result = ncards;
+
+ return (cards);
+ }
+#endif
+ return (DoFilterCardNames(pattern, result));
+}
+
+static char **
+DoFilterCardNames(char *pattern, int *result)
+{
+ FILE *fp;
+ char **cards = NULL;
+ int len, ncards = 0;
+ char *cmd, *ptr, buffer[256];
+
+ cmd = malloc(32 + (strlen(pattern) * 2) + strlen(Cards));
+
+ strcpy(cmd, "egrep -i '^NAME\\ .*");
+ len = strlen(cmd);
+ ptr = pattern;
+ while (*ptr) {
+ if (!isalnum(*ptr)) {
+ cmd[len++] = '\\';
+ }
+ cmd[len++] = *ptr++;
+ }
+ cmd[len] = '\0';
+ strcat(cmd, ".*$' ");
+ strcat(cmd, Cards);
+ strcat(cmd, " | sort");
+ /*sprintf(cmd, "egrep -i '^NAME\\ .*%s.*$' %s | sort", pattern, Cards);*/
+
+ if ((fp = popen(cmd, "r")) == NULL) {
+ fprintf(stderr, "Cannot read Cards database.\n");
+ exit(1);
+ }
+ while (fgets(buffer, sizeof(buffer), fp) != NULL) {
+ ptr = buffer + strlen(buffer) - 1;
+ while (isspace(*ptr) && ptr > buffer)
+ --ptr;
+ if (!isspace(*ptr) && ptr > buffer)
+ ptr[1] = '\0';
+ ptr = buffer;
+ while (!isspace(*ptr) && *ptr) /* skip NAME */
+ ++ptr;
+ while (isspace(*ptr) && *ptr)
+ ++ptr;
+ if (ncards % 16 == 0) {
+ if ((cards = (char**)realloc(cards, sizeof(char*) *
+ (ncards + 16))) == NULL) {
+ fprintf(stderr, "Out of memory.\n");
+ exit(1);
+ }
+ }
+ cards[ncards++] = strdup(ptr);
+ }
+ free(cmd);
+
+ *result = ncards;
+
+ return (cards);
+}
+
+static int
+ReadCardsLine(FILE *fp, char *value)
+{
+ char name[32], buffer[256], *ptr, *end;
+ int result = NOTUSEFUL;
+
+ ++linenum;
+
+ if (fgets(buffer, sizeof(buffer), fp) == NULL)
+ return (END);
+
+ ptr = buffer;
+ /* skip initial spaces; should'nt bother about this.. */
+ while (isspace(*ptr) && *ptr)
+ ++ptr;
+
+ if (*ptr == '#' || *ptr == '\0')
+ return (NOTUSEFUL);
+
+ end = ptr;
+ while (!isspace(*end) && *end)
+ ++end;
+ if (end - ptr > sizeof(buffer) - 1) {
+ strncpy(value, buffer, 255);
+ value[255] = '\0';
+ return (ERROR);
+ }
+ strncpy(name, ptr, end - ptr);
+ name[end - ptr] = '\0';
+
+ /* read the optional arguments */
+ ptr = end;
+ while (isspace(*ptr) && *ptr)
+ ++ptr;
+
+ end = ptr + strlen(ptr) - 1;
+ while (isspace(*end) && end > ptr)
+ --end;
+ if (!isspace(*end))
+ ++end;
+ *end = '\0';
+
+ if (strcmp(name, "NAME") == 0)
+ result = NAME;
+ else if (strcmp(name, "CHIPSET") == 0)
+ result = CHIPSET;
+ else if (strcmp(name, "SERVER") == 0)
+ result = SERVER;
+ else if (strcmp(name, "DRIVER") == 0)
+ result = DRIVER;
+ else if (strcmp(name, "RAMDAC") == 0)
+ result = RAMDAC;
+ else if (strcmp(name, "CLOCKCHIP") == 0)
+ result = CLOCKCHIP;
+ else if (strcmp(name, "DACSPEED") == 0)
+ result = DACSPEED;
+ else if (strcmp(name, "NOCLOCKPROBE") == 0)
+ result = NOCLOCKPROBE;
+ else if (strcmp(name, "UNSUPPORTED") == 0)
+ result = UNSUPPORTED;
+ else if (strcmp(name, "SEE") == 0)
+ result = SEE;
+ else if (strcmp(name, "LINE") == 0)
+ result = LINE;
+ else if (strcmp(name, "END") == 0)
+ result = END;
+ else {
+ strcpy(value, name);
+ return (UNKNOWN);
+ }
+
+ /* value *must* have at least 256 bytes */
+ strcpy(value, ptr);
+
+ return (result);
+}
+
+static int
+CompareCards(_Xconst void *left, _Xconst void *right)
+{
+ return strcasecmp((*(CardsEntry**)left)->name, (*(CardsEntry**)right)->name);
+}
+
+static int
+BCompareCards(_Xconst void *name, _Xconst void *card)
+{
+ return (strcasecmp((char*)name, (*(CardsEntry**)card)->name));
+}
diff --git a/hw/xfree86/utils/xorgcfg/cards.h b/hw/xfree86/utils/xorgcfg/cards.h
new file mode 100644
index 000000000..0e5ee328f
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/cards.h
@@ -0,0 +1,90 @@
+/*
+ * 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/cards.h,v 1.3 2002/07/15 20:46:04 dawes Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <X11/Xfuncproto.h>
+#include <X11/Xmd.h>
+#include <X11/Intrinsic.h>
+#include <X11/Xmu/SysUtil.h>
+
+#ifndef _xf86cfg_cards_h
+#define _xf86cfg_cards_h
+
+#ifdef USE_MODULES
+#ifdef CARDS_PRIVATE
+#include "loader.h"
+
+#include "xf86PciStr.h"
+#include "xf86PciIds.h"
+#endif /* CARDS_PRIVATE */
+#endif /* USE_MODULES */
+
+/* Flags in CardsEntry */
+#define F_NOCLOCKPROBE 0x1 /* Never probe clocks of the card. */
+#define F_UNSUPPORTED 0x2 /* Card is not supported (only VGA). */
+
+/*
+ * Types
+ */
+typedef struct {
+ char *name; /* Name of the card. */
+ char *chipset; /* Chipset (decriptive). */
+ char *server; /* Server identifier. */
+ char *driver; /* Driver identifier. */
+ char *ramdac; /* Ramdac identifier. */
+ char *clockchip; /* Clockchip identifier. */
+ char *dacspeed; /* DAC speed rating. */
+ int flags;
+ char *lines; /* Additional Device section lines. */
+ char *see; /* Must resolve in a last step.
+ * Allow more than one SEE entry? */
+} CardsEntry;
+
+extern CardsEntry **CardsDB;
+extern int NumCardsEntry;
+
+/*
+ * Prototypes
+ */
+void ReadCardsDatabase(void);
+CardsEntry *LookupCard(char*);
+char **GetCardNames(int*);
+char **FilterCardNames(char*, int*);
+#ifdef USE_MODULES
+void InitializePciInfo(void);
+typedef struct _xf86cfgModuleOptions *xf86cfgModuleOptionsPtr;
+void CheckChipsets(xf86cfgModuleOptionsPtr, int*);
+#endif
+
+#endif /* _xf86cfg_cards_h */
diff --git a/hw/xfree86/utils/xorgcfg/computer.xpm b/hw/xfree86/utils/xorgcfg/computer.xpm
new file mode 100644
index 000000000..75fc85b26
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/computer.xpm
@@ -0,0 +1,91 @@
+/* XPM */
+/*
+ * 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/computer.xpm,v 1.1 2000/04/04 22:36:58 dawes Exp $
+ */
+static char * computer_xpm[] = {
+"30 50 8 1",
+" c none",
+". c #CF3CCF3CCF3C",
+"X c #B6DABAEAB6DA",
+"o c #8E388E388E38",
+"O c #FFFFFFFFFFFF",
+"+ c #FFFF00000000",
+"@ c #514451445144",
+"# c #0000FFFF0000",
+" ............................ ",
+"..XXXXXXXXXXXXXXXXXXXXXXXXXXXo",
+".XXXXXXXXXXXXXXXXXXXXXXXXXXXXo",
+".XXooooooooooooooooooooooooXXo",
+".XXo.......................XXo",
+".XXo.XXXXXXXXXXXXXXXXXXXXo.XXo",
+".XXo.XX....XXXXXXXXXXXOoXo.XXo",
+".XXo.XXooooXXXXXXXXXXXooXo.XXo",
+".XXo.XXXXXXXXXXXXXXXXXXXXo.XXo",
+".XXo.......................XXo",
+".XXooooooooooooooooooooooooXXo",
+".XXo.......................XXo",
+".XXo.XXXXXXXXXXXXXXXXXXXXo.XXo",
+".XXo.XXXXXXXXXXXXXXXXXXXXo.XXo",
+".XXo.XXXXXXXXXXXXXXXXXXXXo.XXo",
+".XXooooooooooooooooooooooo.XXo",
+".XXo.......................XXo",
+".XXoooooooooooooo.XXXXXXXo.XXo",
+".XXo..............XXXXXXXo.XXo",
+".XXo.XXXXXXXXXXXX.XX.O.XXo.XXo",
+".XXo.oooooooooooX.XXO+OXXo.XXo",
+".XXo.XXXXXXXXXOOX.XX.O.XXo.XXo",
+".XXo.XXXXXXXXXXXX.XXXXXXXo.XXo",
+".XXo..............XXXXXXXo.XXo",
+".XXooooooooooooooooooooooo.XXo",
+".XXo.XXXXXXXXXXXXXXXXXXXXo.XXo",
+".XXo.XXXXXXXXXXXXXXXXXXXXo.XXo",
+".XXo.XXX@@@@@@@@@XXX...XXo.XXo",
+".XXo.XX@@+@@@@@#@@X.OXXoXo.XXo",
+".XXo.XXX@@@@@@@@@XXXoooXXo.XXo",
+".XXo.XXXXXXXXXXXXXXXXXXXXo.XXo",
+".XXo.XXXXXXXXXXXXXXXXXXXXo.XXo",
+".XXo.XXXXXXXXXXXXXXX..XXXo.XXo",
+".XXo.XXXXXXXXXXXXXX.OXoXXo.XXo",
+".XXo.XXXXXXXXXXXXXXXooXXXo.XXo",
+".XXo.XXXXXXXXXXXXXXXXXXXXo.XXo",
+".XXo.XXXXXXXXXXXXXXXXXXXXo.XXo",
+".XXo.XXXXXXXXXXXXXXXXXXXXo.XXo",
+".XXXo.XXXXXXXXXXXXXXXXXXo.XXXo",
+".XXXo.XXXXXXXXXXXXXXXXXXo.XXXo",
+".XXXo.XXXXXXXXXXXXXXXXXXo.XXXo",
+".XXXo.oXXXoXXXoXXXoXXXoXo.XXXo",
+".XXXXo.XXXXXXXXXXXXXXXXo.XXXXo",
+".XXXXo..oXXXoXXXoXXoXXoo.XXXXo",
+".XXXXXoo..XXXXXXXXXXoo..XXXXXo",
+".XXXXXXXoo......oooo..XXXXXXXo",
+".XXXXXXXXXoooooo....XXXXXXXXXo",
+".XXXXXXXXXXXXXXXXXXXXXXXXXXXXo",
+".XXXXXXXXXXXXXXXXXXXXXXXXXXXoo",
+" oooooooooooooooooooooooooooo "};
diff --git a/hw/xfree86/utils/xorgcfg/config.c b/hw/xfree86/utils/xorgcfg/config.c
new file mode 100644
index 000000000..929999f9e
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/config.c
@@ -0,0 +1,302 @@
+/*
+ * 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/config.c,v 1.8 2002/10/21 04:18:36 paulo Exp $
+ */
+
+#include "config.h"
+#include "mouse-cfg.h"
+#include "keyboard-cfg.h"
+#include "card-cfg.h"
+#include "monitor-cfg.h"
+#include "screen-cfg.h"
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/Paned.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Shell.h>
+
+/*
+ * Prototypes
+ */
+void BackCallback(Widget, XtPointer, XtPointer);
+void NextCallback(Widget, XtPointer, XtPointer);
+void ApplyCallback(Widget, XtPointer, XtPointer);
+void CloseCallback(Widget, XtPointer, XtPointer);
+void ErrorCallback(Widget, XtPointer, XtPointer);
+
+/*
+ * Initialization
+ */
+XF86SetupFunction mouse_functions[] = {
+ MouseDeviceAndProtocol,
+};
+
+XF86SetupFunction keyboard_functions[] = {
+ KeyboardModelAndLayout,
+};
+
+XF86SetupFunction card_functions[] = {
+ CardModel,
+};
+
+XF86SetupFunction monitor_functions[] = {
+ MonitorLayout,
+};
+
+XF86SetupFunction screen_functions[] = {
+ ScreenDialog,
+};
+
+XF86SetupFunctionList function_lists[] = {
+ {mouse_functions, sizeof(mouse_functions) / sizeof(mouse_functions[0]),},
+ {keyboard_functions, sizeof(keyboard_functions) / sizeof(keyboard_functions[0]),},
+ {card_functions, sizeof(card_functions) / sizeof(card_functions[0]),},
+ {monitor_functions, sizeof(monitor_functions) / sizeof(monitor_functions[0]),},
+ {screen_functions, sizeof(screen_functions) / sizeof(screen_functions[0]),},
+};
+
+XF86SetupInfo xf86info = {
+ sizeof(function_lists) / sizeof(function_lists[0]),
+ MOUSE,
+ function_lists,
+};
+
+Widget configp, current, ok, back, next;
+static Widget shell, errcurrent, oldcurrent;
+
+static int config_status, config_popped;
+
+static ConfigCheckFunction config_function;
+
+Widget ident_widget;
+char *ident_string;
+XF86ConfigPtr XF86Config;
+
+/*
+ * Implementation
+ */
+void
+StartConfig(void)
+{
+ static int first = 1;
+ Widget pane, top, label, bottom, cancel;
+ const char *filename;
+
+ if (!first)
+ return;
+ first = 0;
+
+ /* Read initial configuration */
+ if ((filename = xf86openConfigFile(getuid() == 0 ? CONFPATH : USER_CONFPATH,
+ XF86Config_path, NULL)) == NULL) {
+ int length = XF86Config_path ? strlen(XF86Config_path) : -1;
+
+ if (length > 2 &&
+ XF86Config_path[length - 2] == '-' &&
+ XF86Config_path[length - 1] == '4') {
+ XF86Config_path[length - 2] = '\0';
+ filename = xf86openConfigFile(getuid() == 0 ?
+ CONFPATH : USER_CONFPATH,
+ XF86Config_path, NULL);
+ }
+
+ if (filename == NULL) {
+ fprintf(stderr, "Cannot open config file.\n");
+ exit(1);
+ }
+ }
+ XF86Config_path = (char *)filename;
+ if ((XF86Config = xf86readConfigFile()) == NULL) {
+ fprintf(stderr, "Problem when parsing config file\n");
+ exit(1);
+ }
+
+ shell = XtCreatePopupShell("config", transientShellWidgetClass,
+ toplevel, NULL, 0);
+ pane = XtCreateManagedWidget("pane", panedWidgetClass,
+ shell, NULL, 0);
+ top = XtCreateManagedWidget("top", formWidgetClass,
+ pane, NULL, 0);
+ label = XtCreateManagedWidget("label", labelWidgetClass,
+ top, NULL, 0);
+ ident_widget = XtVaCreateManagedWidget("identifier", asciiTextWidgetClass,
+ top,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ configp = XtCreateManagedWidget("work", formWidgetClass,
+ pane, NULL, 0);
+ current = XtCreateManagedWidget("wellcome", labelWidgetClass,
+ configp, NULL, 0);
+ bottom = XtCreateManagedWidget("bottom", formWidgetClass,
+ pane, NULL, 0);
+ back = XtCreateManagedWidget("back", commandWidgetClass,
+ bottom, NULL, 0);
+ XtAddCallback(back, XtNcallback, BackCallback, (XtPointer)&xf86info);
+ next = XtCreateManagedWidget("next", commandWidgetClass,
+ bottom, NULL, 0);
+ XtAddCallback(next, XtNcallback, NextCallback, (XtPointer)&xf86info);
+ ok = XtCreateManagedWidget("ok", commandWidgetClass,
+ bottom, NULL, 0);
+ XtAddCallback(ok, XtNcallback, ApplyCallback, (XtPointer)NULL);
+ cancel = XtCreateManagedWidget("cancel", commandWidgetClass,
+ bottom, NULL, 0);
+ XtAddCallback(cancel, XtNcallback, CloseCallback, (XtPointer)NULL);
+
+ XtRealizeWidget(shell);
+
+ XSetWMProtocols(DPY, XtWindow(shell), &wm_delete_window, 1);
+}
+
+/*ARGSUSED*/
+Bool
+ConfigLoop(ConfigCheckFunction config_fn)
+{
+ Arg args[1];
+ config_popped = True;
+ XtPopup(shell, XtGrabExclusive);
+
+ config_function = config_fn;
+ while (config_popped)
+ XtAppProcessEvent(XtWidgetToApplicationContext(shell), XtIMAll);
+
+ XtSetArg(args[0], XtNstring, &ident_string);
+ XtGetValues(ident_widget, args, 1);
+
+ return (config_status);
+}
+
+/*ARGSUSED*/
+void
+ConfigError(void)
+{
+ static int first = 1;
+
+ if (first) {
+ Widget label, command;
+
+ errcurrent = XtCreateWidget("error", formWidgetClass,
+ configp, NULL, 0);
+ label = XtCreateManagedWidget("label", labelWidgetClass,
+ errcurrent, NULL, 0);
+ command = XtCreateManagedWidget("command", commandWidgetClass,
+ errcurrent, NULL, 0);
+ XtAddCallback(command, XtNcallback, ErrorCallback, NULL);
+
+ XtRealizeWidget(errcurrent);
+ }
+
+ oldcurrent = current;
+ XtChangeManagedSet(&current, 1, NULL, NULL, &errcurrent, 1);
+ current = errcurrent;
+
+ XtSetSensitive(ok, False);
+}
+
+/*ARGSUSED*/
+void
+ErrorCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XtChangeManagedSet(&errcurrent, 1, NULL, NULL, &oldcurrent, 1);
+ current = oldcurrent;
+
+ XtSetSensitive(ok, True);
+}
+
+/*ARGSUSED*/
+void
+BackCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XF86SetupInfo *info = (XF86SetupInfo*)user_data;
+ int idx = info->lists[info->cur_list].cur_function - 1;
+
+ if (idx >= 0 && info->lists[info->cur_list].num_functions > 0) {
+ info->lists[info->cur_list].cur_function = idx;
+ if (idx - 1 == -1)
+ XtSetSensitive(back, False);
+ if (!XtIsSensitive(next))
+ XtSetSensitive(next, True);
+ (info->lists[info->cur_list].functions[idx])(info);
+ }
+}
+
+/*ARGSUSED*/
+void
+NextCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XF86SetupInfo *info = (XF86SetupInfo*)user_data;
+ int idx = info->lists[info->cur_list].cur_function + 1;
+
+ if (idx < info->lists[info->cur_list].num_functions) {
+ info->lists[info->cur_list].cur_function = idx;
+ if (idx + 1 == info->lists[info->cur_list].num_functions)
+ XtSetSensitive(next, False);
+ if (!XtIsSensitive(back))
+ XtSetSensitive(back, True);
+ (info->lists[info->cur_list].functions[idx])(info);
+ }
+}
+
+/*ARGSUSED*/
+void
+CloseCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XtPopdown(shell);
+ config_popped = False;
+ config_status = False;
+ /* make sure it is sensitive */
+ XtSetSensitive(ok, True);
+ xf86info.lists[xf86info.cur_list].cur_function = 0;
+}
+
+/*ARGSUSED*/
+void
+ApplyCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[1];
+
+ XtSetArg(args[0], XtNstring, &ident_string);
+ XtGetValues(ident_widget, args, 1);
+
+ if (config_function == NULL || (*config_function)()) {
+ XtPopdown(shell);
+ config_popped = False;
+ config_status = True;
+ xf86info.lists[xf86info.cur_list].cur_function = 0;
+ }
+ else
+ ConfigError();
+}
+
+/*ARGSUSED*/
+void
+ConfigCancelAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+ CloseCallback(w, NULL, NULL);
+}
diff --git a/hw/xfree86/utils/xorgcfg/config.h b/hw/xfree86/utils/xorgcfg/config.h
new file mode 100644
index 000000000..34b8d7e52
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/config.h
@@ -0,0 +1,227 @@
+/*
+ * 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/config.h,v 1.16 2002/05/31 18:46:03 dawes Exp $
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xmu/SysUtil.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <string.h>
+#include <unistd.h>
+#if defined(sun) && defined(SVR4)
+#include <strings.h>
+#endif
+
+#include <stdarg.h>
+
+#ifdef __UNIXOS2__
+#define strcasecmp stricmp
+#define setenv putenv
+#define PATH_MAX 260
+#endif
+
+/* Get PATH_MAX */
+#ifndef PATH_MAX
+# if defined(_POSIX_SOURCE)
+# include <limits.h>
+# else
+# define _POSIX_SOURCE
+# include <limits.h>
+# undef _POSIX_SOURCE
+# endif
+# ifndef PATH_MAX
+# ifdef MAXPATHLEN
+# define PATH_MAX MAXPATHLEN
+# else
+# define PATH_MAX 1024
+# endif
+# endif
+#endif
+
+#include <xf86Parser.h>
+#include <X11/XKBlib.h>
+#include <X11/extensions/XKBgeom.h>
+#include <X11/extensions/XKM.h>
+#include <X11/extensions/XKBfile.h>
+#include <X11/extensions/XKBui.h>
+#include <X11/extensions/XKBrules.h>
+
+#ifndef _xf86cfg_config_h
+#define _xf86cfg_config_h
+
+/* Must match the offset in the xf86info structure at config.c,
+ * and is used also by interface.c
+ */
+#define MOUSE 0
+#define KEYBOARD 1
+#define CARD 2
+#define MONITOR 3
+#define SCREEN 4
+#define SERVER 5
+
+#define UNUSED 0
+#define USED 1
+
+#define CONFIG_LAYOUT 0
+#define CONFIG_SCREEN 1
+#define CONFIG_MODELINE 2
+#define CONFIG_ACCESSX 3
+extern int config_mode;
+
+#define CONFPATH "%A," "%R," \
+ "/etc/X11/%R," "%P/etc/X11/%R," \
+ "%E," "%F," \
+ "/etc/X11/%F," "%P/etc/X11/%F," \
+ "%D/%X," \
+ "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
+ "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
+ "%P/etc/X11/%X," \
+ "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
+ "%P/lib/X11/%X"
+#define USER_CONFPATH "/etc/X11/%S," "%P/etc/X11/%S," \
+ "/etc/X11/%G," "%P/etc/X11/%G," \
+ "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
+ "%P/etc/X11/%X," \
+ "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
+ "%P/lib/X11/%X"
+
+/*
+ * Types
+ */
+typedef struct _XF86SetupInfo XF86SetupInfo;
+typedef void (*XF86SetupFunction)(XF86SetupInfo*);
+
+typedef struct _XF86SetupFunctionList {
+ XF86SetupFunction *functions;
+ int num_functions;
+ int cur_function;
+} XF86SetupFunctionList;
+
+struct _XF86SetupInfo {
+ int num_lists;
+ int cur_list;
+ XF86SetupFunctionList *lists;
+};
+
+typedef Bool (*ConfigCheckFunction)(void);
+
+typedef struct _xf86cfgDevice xf86cfgDevice;
+
+struct _xf86cfgDevice {
+ XtPointer config;
+ Widget widget;
+ int type, state, refcount;
+};
+
+typedef struct {
+ XF86ConfScreenPtr screen;
+ Widget widget;
+ int type, state, refcount;
+ xf86cfgDevice *card;
+ xf86cfgDevice *monitor;
+ short row, column;
+ XRectangle rect;
+ short rotate;
+} xf86cfgScreen;
+
+/* this structure is used just to restore
+ properly the monitors layout in the
+ screen window configuration.
+ */
+typedef struct {
+ XF86ConfLayoutPtr layout;
+ xf86cfgScreen **screen;
+ XPoint *position;
+ int num_layouts;
+} xf86cfgLayout;
+
+/* The vidmode extension usage is controlled by this structure.
+ * The information is read at startup, and added monitors cannot
+ * be configured, since they are not attached to a particular screen.
+ */
+typedef struct _xf86cfgVidMode xf86cfgVidmode;
+
+typedef struct {
+ XF86ConfLayoutPtr layout; /* current layout */
+ Widget cpu;
+ xf86cfgLayout **layouts;
+ Cardinal num_layouts;
+ xf86cfgScreen **screens;
+ Cardinal num_screens;
+ xf86cfgDevice **devices;
+ Cardinal num_devices;
+ xf86cfgVidmode **vidmodes;
+ Cardinal num_vidmodes;
+} xf86cfgComputer;
+
+/*
+ * Prototypes
+ */
+void StartConfig(void);
+Bool ConfigLoop(ConfigCheckFunction);
+void ConfigError(void);
+void ChangeScreen(XF86ConfMonitorPtr, XF86ConfMonitorPtr,
+ XF86ConfDevicePtr, XF86ConfDevicePtr);
+void SetTip(xf86cfgDevice*);
+Bool startx(void);
+void endx(void);
+void startaccessx(void);
+void ConfigCancelAction(Widget, XEvent*, String*, Cardinal*);
+void ExpertConfigureStart(void);
+void ExpertConfigureEnd(void);
+void ExpertCloseAction(Widget, XEvent*, String*, Cardinal*);
+void ExpertCallback(Widget, XtPointer, XtPointer);
+
+/*
+ * Initialization
+ */
+extern Widget toplevel, configp, current, back, next;
+extern XtAppContext appcon;
+extern XF86SetupInfo xf86info;
+extern Widget ident_widget;
+extern char *ident_string;
+extern XF86ConfigPtr XF86Config;
+extern char *XF86Config_path;
+extern char *XF86Module_path;
+extern char *XFree86_path;
+extern char *XF86Font_path;
+extern char *XF86RGB_path;
+extern char *XFree86Dir;
+extern xf86cfgComputer computer;
+extern Atom wm_delete_window;
+extern Display *DPY;
+extern Pixmap menuPixmap;
+#ifdef USE_MODULES
+extern int nomodules;
+#endif
+
+#endif /* _xf86cfg_config_h */
diff --git a/hw/xfree86/utils/xorgcfg/down.xbm b/hw/xfree86/utils/xorgcfg/down.xbm
new file mode 100644
index 000000000..742adf202
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/down.xbm
@@ -0,0 +1,8 @@
+#define down_width 19
+#define down_height 19
+static unsigned char down_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00,
+ 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00,
+ 0x80, 0x0f, 0x00, 0xfc, 0xff, 0x01, 0xf8, 0xff, 0x00, 0xf0, 0x7f, 0x00,
+ 0xe0, 0x3f, 0x00, 0xc0, 0x1f, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x07, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
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);
+}
diff --git a/hw/xfree86/utils/xorgcfg/help.c b/hw/xfree86/utils/xorgcfg/help.c
new file mode 100644
index 000000000..2b25e8ede
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/help.c
@@ -0,0 +1,1786 @@
+/*
+ * 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/help.c,v 1.7 2002/06/06 21:03:32 paulo Exp $
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Shell.h>
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Paned.h>
+
+#include <X11/Xaw/Text.h>
+#include <X11/Xaw/TextSinkP.h>
+#include <X11/Xaw/TextSrcP.h>
+#include <X11/Xmu/SysUtil.h>
+#include <X11/Xmu/Xmu.h>
+#include <stdlib.h> /* for bsearch() */
+#include <ctype.h>
+#include "help.h"
+#include "options.h"
+
+/*
+ * Prototypes
+ */
+static void CloseCallback(Widget, XtPointer, XtPointer);
+static void StartHelp(void);
+void Html_ModeStart(Widget);
+
+/*
+ * Initialization
+ */
+static Widget shell, text;
+static Bool popped_up = False;
+
+/*
+ * Implementation
+ */
+void
+Help(char *topic)
+{
+ Widget source;
+ char *str = NULL;
+ Bool error = False;
+ static char *def_text = "<h2>Help Error</h2>"
+ "No help available for the topic <b>%s</b>.";
+ XtResource resource = {
+ NULL, "HelpMessage", XtRString, sizeof(char*),
+ 0, XtRString, NULL
+ };
+
+ StartHelp();
+ source = XawTextGetSource(text);
+ XawTextSourceClearEntities(source, 0,
+ XawTextSourceScan(source, 0, XawstAll,
+ XawsdRight, 1, True));
+ if (topic != NULL) {
+ resource.resource_name = topic;
+ XtGetApplicationResources(shell, (XtPointer)&str,
+ &resource, 1, NULL, 0);
+ }
+ if (str == NULL) {
+ int len;
+
+ error = True;
+ if (topic == NULL)
+ topic = "(null argument)";
+ str = XtMalloc(len = strlen(topic) + strlen(def_text) + 1);
+ XmuSnprintf(str, len, def_text, topic);
+ }
+ XtVaSetValues(text, XtNstring, str, NULL, 0);
+ if (error)
+ XtFree(str);
+
+ Html_ModeStart(source);
+ _XawTextBuildLineTable((TextWidget)text,
+ XawTextTopPosition(text), True);
+ XawTextDisplay(text);
+ if (popped_up == False) {
+ popped_up = True;
+ XtPopup(shell, XtGrabNone);
+ XtSetKeyboardFocus(shell, text);
+ }
+}
+
+static void
+StartHelp(void)
+{
+ static XtResource resource = {
+ "properties", "Properties", XtRString, sizeof(char*),
+ 0, XtRString, NULL
+ };
+
+ if (shell == NULL) {
+ Widget pane, commands, close;
+ char *props;
+ XawTextPropertyList *propl;
+
+ shell = XtCreatePopupShell("help", transientShellWidgetClass,
+ toplevel, NULL, 0);
+ pane = XtCreateManagedWidget("pane", panedWidgetClass,
+ shell, NULL, 0);
+ text = XtVaCreateManagedWidget("text", asciiTextWidgetClass,
+ pane, XtNeditType, XawtextRead, NULL, 0);
+ commands = XtCreateManagedWidget("commands", formWidgetClass, pane,
+ NULL, 0);
+ close = XtCreateManagedWidget("close", commandWidgetClass,
+ commands, NULL, 0);
+ XtAddCallback(close, XtNcallback, CloseCallback, NULL);
+ XtRealizeWidget(shell);
+ XSetWMProtocols(DPY, XtWindow(shell), &wm_delete_window, 1);
+ XtGetApplicationResources(text, (XtPointer)&props,
+ &resource, 1, NULL, 0);
+ propl = XawTextSinkConvertPropertyList("html", props,
+ toplevel->core.screen,
+ toplevel->core.colormap,
+ toplevel->core.depth);
+ XtVaSetValues(XawTextGetSink(text), XawNtextProperties, propl, NULL, 0);
+ }
+}
+
+/*ARGSUSED*/
+static void
+CloseCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XtPopdown(shell);
+ popped_up = False;
+}
+
+/*ARGSUSED*/
+void
+HelpCancelAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+ CloseCallback(w, NULL, NULL);
+}
+
+
+/* bellow is a modified version of the html-mode.c I wrote for xedit
+ * (at least) temporarily dead.
+ */
+
+/*
+ * Copyright (c) 1999 by The XFree86 Project, Inc.
+ *
+ * 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
+ * THE XFREE86 PROJECT 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 the XFree86 Project shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization from the
+ * XFree86 Project.
+ *
+ * Author: Paulo César Pereira de Andrade
+ */
+
+#define Html_Peek(parser) ((parser)->next)
+
+/*
+ * Types
+ */
+typedef struct _Html_Parser Html_Parser;
+typedef struct _Html_Item Html_Item;
+
+typedef struct _Html_TagInfo {
+ char *name;
+ int entity : 1; /* it changes the type of the text */
+ int nest : 1; /* does not close tags automatically */
+ int end : 1; /* need a close markup */
+ int adnl : 1; /* add newline before/after tag contents */
+ int para : 1; /* changes the paragraph formatting */
+ unsigned long mask; /* enforce use of attributes of this tag-info */
+ unsigned long xlfd_mask;
+ void (*parse_args)(Html_Parser*, Html_Item*);
+ XawTextProperty *override;
+ XrmQuark ident;
+} Html_TagInfo;
+
+struct _Html_Item {
+ XrmQuark ident;
+ XawTextPosition start, end;
+ Html_TagInfo *info;
+
+ XawTextProperty *combine;
+ Bool override;
+ int li;
+
+ XtPointer replace;
+
+ Html_Item *parent, *child, *next;
+};
+
+struct _Html_Parser {
+ Widget source;
+ XawTextBlock block, replace;
+ XawTextPosition position, offset, start, end, last;
+ XrmQuark quark;
+ int i, ch, next;
+ Html_Item *item, *head;
+ XmuScanline *mask;
+ int space, pre, adnl, list, desc, column;
+ Bool spc;
+ XawTextBlock *entity;
+
+ Pixel alink;
+};
+
+typedef struct _Html_SourceInfo Html_SourceInfo;
+struct _Html_SourceInfo {
+ Widget source;
+ XawTextBlock block;
+ XawTextPosition last;
+ Html_SourceInfo *next;
+};
+
+/*
+ * Proptotypes
+ */
+void Html_ModeEnd(Widget);
+static void Html_ModeInit(void);
+static void Html_ParseCallback(Widget, XtPointer, XtPointer);
+static Html_TagInfo *Html_GetInfo(char*);
+static int Html_Get(Html_Parser*);
+static int Html_Parse1(Html_Parser*);
+static int Html_Parse2(Html_Parser*);
+static void Html_ParseTag(Html_Parser*);
+static void Html_Commit(Html_Parser*);
+static void Html_AddEntities(Html_Parser*, Html_Item*);
+
+static int Html_Put(Html_Parser*, int);
+static void Html_Puts(Html_Parser*, char*);
+static int Html_Format1(Html_Parser*);
+static int Html_Format2(Html_Parser*);
+static int Html_Format3(Html_Parser*);
+static void Html_FormatTag(Html_Parser*);
+
+static void Html_AArgs(Html_Parser*, Html_Item*);
+static void Html_FontArgs(Html_Parser*, Html_Item*);
+
+/*
+ * Initialization
+ */
+static XrmQuark
+ Qbr,
+ Qdefault,
+ Qdd,
+ Qdl,
+ Qdt,
+ Qentity,
+ Qetag,
+ Qhide,
+ Qli,
+ Qol,
+ Qp,
+ Qpre,
+ Qspace,
+ Qtag,
+ Qul;
+
+static Html_TagInfo tag_info[] = {
+ {"a", 1, 0, 1, 0, 0,
+ 0, 0,
+ Html_AArgs},
+ {"address", 1, 0, 1, 0, 0,
+ 0, XAW_TPROP_SLANT,
+ },
+ {"b", 1, 0, 1, 0, 0,
+ 0, XAW_TPROP_WEIGHT,
+ },
+ {"blockquote", 0, 1, 1, 1, 1,
+ 0, 0,
+ },
+ {"body", 0, 0, 1, 0, 0,
+ 0, 0,
+ },
+ {"br", 0, 0, 0, 0, 0,
+ },
+ {"code", 1, 0, 1, 0, 0,
+ 0, XAW_TPROP_FAMILY | XAW_TPROP_PIXELSIZE,
+ },
+ {"dd", 0, 1, 1, 0, 1,
+ 0, 0},
+ {"dl", 0, 1, 1, 0, 0,
+ 0, 0,
+ },
+ {"dt", 0, 0, 1, 0, 0,
+ 0, 0},
+ {"em", 1, 0, 1, 0, 0,
+ 0, XAW_TPROP_SLANT,
+ },
+ {"font", 1, 1, 1, 0, 0,
+ 0, 0,
+ Html_FontArgs},
+ {"h1", 1, 0, 1, 1, 0,
+ 0, XAW_TPROP_WEIGHT | XAW_TPROP_PIXELSIZE,
+ },
+ {"h2", 1, 0, 1, 1, 0,
+ 0, XAW_TPROP_WEIGHT | XAW_TPROP_PIXELSIZE,
+ },
+ {"h3", 1, 0, 1, 1, 0,
+ 0, XAW_TPROP_WEIGHT | XAW_TPROP_PIXELSIZE,
+ },
+ {"h4", 1, 0, 1, 1, 0,
+ 0, XAW_TPROP_WEIGHT | XAW_TPROP_PIXELSIZE,
+ },
+ {"h5", 1, 0, 1, 1, 0,
+ 0, XAW_TPROP_WEIGHT | XAW_TPROP_PIXELSIZE,
+ },
+ {"h6", 1, 0, 1, 1, 0,
+ 0, XAW_TPROP_WEIGHT | XAW_TPROP_PIXELSIZE,
+ },
+ {"head", 0, 0, 1, 0, 0,
+ 0, 0,
+ },
+ {"html", 0, 0, 1, 0, 0,
+ 0, 0,
+ },
+ {"i", 1, 0, 1, 0, 0,
+ 0, XAW_TPROP_SLANT,
+ },
+ {"kbd", 1, 0, 1, 0, 0,
+ 0, XAW_TPROP_FAMILY | XAW_TPROP_PIXELSIZE,
+ },
+ {"li", 0, 0, 0, 0, 0,
+ 0, 0},
+ {"ol", 0, 1, 1, 0, 1,
+ 0, 0,
+ },
+ {"p", 0, 0, 0, 1, 0,
+ },
+ {"pre", 1, 0, 1, 1, 0,
+ 0, XAW_TPROP_FAMILY | XAW_TPROP_PIXELSIZE,
+ },
+ {"samp", 1, 0, 1, 0, 0,
+ 0, XAW_TPROP_FAMILY | XAW_TPROP_PIXELSIZE,
+ },
+ {"strong", 1, 0, 1, 0, 0,
+ 0, XAW_TPROP_WEIGHT,
+ },
+ {"tt", 1, 0, 1, 0, 0,
+ 0, XAW_TPROP_FAMILY | XAW_TPROP_PIXELSIZE,
+ },
+ {"ul", 0, 1, 1, 0, 1,
+ 0, 0,
+ },
+};
+
+static char *pnl = "<p>\n", *nlpnl = "\n<p>\n";
+static Html_SourceInfo *source_info;
+
+/*
+ * Implementation
+ */
+static char *
+Html_GetText(Widget src, XawTextPosition position)
+{
+ char *result, *tempResult;
+ XawTextPosition offset = 0;
+ XawTextBlock text;
+
+ tempResult = result = XtMalloc((unsigned)(position + 1));
+
+ while (offset < position) {
+ offset = XawTextSourceRead(src, offset, &text, position - offset);
+ if (!text.length)
+ break;
+ memcpy(tempResult, text.ptr, (unsigned)text.length);
+ tempResult += text.length;
+ }
+
+ *tempResult = '\0';
+
+ return (result);
+}
+
+void
+Html_ModeStart(Widget src)
+{
+ Html_Parser *parser = XtNew(Html_Parser);
+ Html_Item *next, *item;
+ XColor color, exact;
+ Html_SourceInfo *info = XtNew(Html_SourceInfo);
+
+ if (XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap,
+ "blue", &color, &exact))
+ parser->alink = color.pixel;
+ else
+ parser->alink = 0L;
+
+ XtVaSetValues(src, XtNeditType, XawtextEdit, NULL, 0);
+
+ Html_ModeInit();
+
+ /* initialize parser state */
+ parser->source = src;
+ parser->position = XawTextSourceRead(parser->source, 0,
+ &parser->block, 4096);
+ parser->replace.ptr = NULL;
+ parser->replace.firstPos = 0;
+ parser->replace.length = 0;
+ parser->replace.format = FMT8BIT;
+ parser->offset = -1;
+ parser->quark = NULLQUARK;
+ parser->i = 0;
+ parser->i = parser->ch = parser->next = 0;
+ parser->last = XawTextSourceScan(src, 0, XawstAll, XawsdRight, 1, 1);
+ if (parser->block.length == 0)
+ parser->ch = parser->next = EOF;
+ else
+ (void)Html_Get(parser);
+ parser->pre = 0;
+ parser->adnl = 1;
+ parser->list = parser->desc = parser->column = 0;
+ parser->spc = True;
+
+ info->source = src;
+ info->block.ptr = Html_GetText(src, parser->last);
+ info->block.length = parser->last;
+ info->block.format = FMT8BIT;
+ info->block.firstPos = 0;
+ info->next = NULL;
+ if (source_info == NULL)
+ source_info = info;
+ else {
+ Html_SourceInfo *tmp = source_info;
+
+ while (tmp->next)
+ tmp = tmp->next;
+ tmp->next = info;
+ }
+
+ while (Html_Format1(parser) != EOF)
+ ;
+ XawTextSourceReplace(parser->source, 0, parser->last, &parser->replace);
+ XtFree(parser->replace.ptr);
+
+ /* re-initialize parser state */
+ parser->position = XawTextSourceRead(parser->source, 0,
+ &parser->block, 4096);
+ parser->offset = -1;
+ parser->quark = NULLQUARK;
+ parser->i = parser->ch = parser->next = 0;
+ parser->last = XawTextSourceScan(src, 0, XawstAll, XawsdRight, 1, 1);
+ info->last = parser->last;
+ if (parser->block.length == 0)
+ parser->ch = parser->next = EOF;
+ else
+ (void)Html_Get(parser);
+ parser->adnl = 1;
+ parser->list = parser->desc = parser->column = 0;
+ parser->spc = True;
+ parser->head = parser->item = NULL;
+
+ parser->mask = XmuNewScanline(0, 0, 0);
+
+ /* build html structure information */
+ while (Html_Parse1(parser) != EOF)
+ ;
+
+ /* create top level entity mask */
+ (void)XmuScanlineNot(parser->mask, 0, parser->last);
+
+ item = parser->item;
+ while (item) {
+ next = item->next;
+ Html_AddEntities(parser, item);
+ if (item->combine)
+ XtFree((XtPointer)item->combine);
+ XtFree((XtPointer)item);
+ item = next;
+ }
+ XmuDestroyScanline(parser->mask);
+
+ XtVaSetValues(src, XtNeditType, XawtextRead, NULL, 0);
+
+ XtFree((XtPointer)parser);
+
+ /* add callbacks for interactive changes */
+ XtAddCallback(src, XtNpropertyCallback, Html_ParseCallback, NULL);
+}
+
+void
+Html_ModeEnd(Widget src)
+{
+ Html_SourceInfo *info, *pinfo;
+
+ XtRemoveCallback(src, XtNpropertyCallback, Html_ParseCallback, NULL);
+ for (pinfo = info = source_info; info; pinfo = info, info = info->next)
+ if (info->source == src)
+ break;
+
+ if (info == NULL)
+ return;
+
+ XawTextSourceClearEntities(src, 0, info->last);
+ XtVaSetValues(src, XtNeditType, XawtextEdit, NULL, 0);
+ XawTextSourceReplace(src, 0, info->last, &info->block);
+ XtVaSetValues(src, XtNeditType, XawtextRead, NULL, 0);
+
+ if (info == source_info)
+ source_info = source_info->next;
+ else
+ pinfo->next = info->next;
+ XtFree(info->block.ptr);
+ XtFree((XtPointer)info);
+}
+
+static void
+Html_ParseCallback(Widget w, XtPointer client_data, XtPointer call_data)
+{
+}
+
+static int
+bcmp_tag_info(_Xconst void *left, _Xconst void *right)
+{
+ return (strcmp((char*)left, ((Html_TagInfo*)right)->name));
+}
+
+static Html_TagInfo *
+Html_GetInfo(char *name)
+{
+ return (bsearch(name, tag_info, sizeof(tag_info) / sizeof(tag_info[0]),
+ sizeof(Html_TagInfo), bcmp_tag_info));
+}
+
+static int
+Html_Get(Html_Parser *parser)
+{
+ if (parser->ch == EOF)
+ return (EOF);
+ if (parser->i >= parser->block.length) {
+ parser->i = 0;
+ parser->position = XawTextSourceRead(parser->source, parser->position,
+ &parser->block, 4096);
+ }
+ parser->ch = parser->next;
+ if (parser->block.length == 0)
+ parser->next = EOF;
+ else
+ parser->next = (unsigned char)parser->block.ptr[parser->i++];
+ parser->offset++;
+
+ return (parser->ch);
+}
+
+static void
+Html_ModeInit(void)
+{
+ static int initialized;
+ int i;
+
+ if (initialized)
+ return;
+
+ Qbr = XrmPermStringToQuark("br");
+ Qdd = XrmPermStringToQuark("dd");
+ Qdefault = XrmPermStringToQuark("default");
+ Qdl = XrmPermStringToQuark("dl");
+ Qdt = XrmPermStringToQuark("dt");
+ Qentity = XrmPermStringToQuark("entity");
+ Qetag = XrmPermStringToQuark("/tag");
+ Qhide = XrmPermStringToQuark("hide");
+ Qli = XrmPermStringToQuark("li");
+ Qol = XrmPermStringToQuark("ol");
+ Qp = XrmPermStringToQuark("p");
+ Qpre = XrmPermStringToQuark("pre");
+ Qspace = XrmPermStringToQuark("space");
+ Qtag = XrmPermStringToQuark("tag");
+ Qul = XrmPermStringToQuark("ul");
+
+ for (i = 0; i < sizeof(tag_info) / sizeof(tag_info[0]); i++)
+ tag_info[i].ident = XrmPermStringToQuark(tag_info[i].name);
+
+ initialized = True;
+}
+
+/************************************************************************/
+/* PARSE */
+/************************************************************************/
+static void
+Html_AddEntities(Html_Parser *parser, Html_Item *item)
+{
+ Html_Item *parent, *next, *child = item->child;
+ XmuSegment segment, *ent;
+ XmuScanline *mask = XmuNewScanline(0, 0, 0);
+ XawTextProperty *tprop, *property = NULL;
+ Widget sink;
+ Bool changed = False;
+
+ /* combine properties */
+ if (item->info &&
+ (item->info->entity ||
+ (item->parent && item->parent->ident != item->parent->info->ident))) {
+ sink = XawTextGetSink(text);
+ parent = item->parent;
+ property = XawTextSinkCopyProperty(sink, item->ident);
+ property->mask = item->info->mask;
+ property->xlfd_mask = item->info->xlfd_mask;
+ if (parent) {
+ (void)XawTextSinkCombineProperty(sink, property,
+ XawTextSinkGetProperty(sink, parent->ident), False);
+ if (item->combine && parent->combine)
+ (void)XawTextSinkCombineProperty(sink, item->combine,
+ parent->combine,
+ item->override);
+ }
+ if (item->combine)
+ XawTextSinkCombineProperty(sink, property, item->combine, True);
+ tprop = property;
+ property = XawTextSinkAddProperty(sink, property);
+ XtFree((XtPointer)tprop);
+ if (property && item->ident != property->identifier) {
+ item->ident = property->identifier;
+ changed = True;
+ }
+ }
+
+ if (item->end < 0) {
+ if (item->next)
+ item->end = item->next->start;
+ else if (item->parent)
+ item->end = item->parent->end;
+ else
+ item->end = parser->last;
+ }
+
+ while (child) {
+ next = child->next;
+ segment.x1 = child->start;
+ segment.x2 = child->end;
+ (void)XmuScanlineOrSegment(mask, &segment);
+ Html_AddEntities(parser, child);
+ if (child->combine)
+ XtFree((XtPointer)child->combine);
+ XtFree((XtPointer)child);
+ child = next;
+ }
+
+ /* build entity mask */
+ (void)XmuScanlineNot(mask, item->start, item->end);
+ (void)XmuScanlineAnd(mask, parser->mask);
+
+ /* add entities */
+ if (item->info && changed) {
+ for (ent = mask->segment; ent; ent = ent->next)
+ (void)XawTextSourceAddEntity(parser->source, 0, 0, NULL, ent->x1,
+ ent->x2 - ent->x1, item->ident);
+ }
+ else if (item->info == NULL)
+ (void)XawTextSourceAddEntity(parser->source, 0,
+ XAW_TENTF_READ | XAW_TENTF_REPLACE,
+ item->replace, item->start,
+ item->end - item->start,
+ item->parent->ident);
+
+ /* set mask for parent entities */
+ (void)XmuScanlineOr(parser->mask, mask);
+ XmuDestroyScanline(mask);
+
+#if 0
+ if (item->info && item->info->para) {
+ XawTextSourceSetParagraph(parser->source, item->start, item->end,
+ 40, /* arbitrary value, for testing */
+ 0, 0);
+ }
+#endif
+}
+
+static void
+Html_Commit(Html_Parser *parser)
+{
+ XawTextPosition position;
+ int length;
+
+ position = parser->start;
+ length = parser->end - parser->start;
+ if (position < 0) {
+ length += position;
+ position = 0;
+ }
+ if (position + length > parser->last + 1)
+ length -= (position + length) - parser->last + 1;
+
+ if (parser->quark != Qdefault && parser->quark != NULLQUARK && length > 0) {
+ XmuSegment segment;
+ Html_Item *head = parser->head;
+ XrmQuark quark = parser->quark;
+
+ parser->quark = Qdefault;
+
+ if (quark == Qli && head &&
+ (head->info->ident == Qol || head->info->ident == Qul)) {
+ if (parser->head == NULL || head->info->ident != Qol)
+ XawTextSourceAddEntity(parser->source, 0, /*XAW_TENT_BULLET,*/
+ XAW_TENTF_HIDE, NULL,
+ position, length, Qli);
+ else
+ XawTextSourceAddEntity(parser->source, 0, /*XAW_TENT_LITEM,*/
+ XAW_TENTF_HIDE,
+ (XtPointer)(long)head->li++,
+ position, length, Qli);
+ }
+ else if (quark == Qhide)
+ XawTextSourceAddEntity(parser->source, 0, XAW_TENTF_HIDE, NULL,
+ position, length, quark);
+ else if (quark == Qentity) {
+ if (head && head->end == -1) {
+ Html_Item *item, *it;
+
+ item = XtNew(Html_Item);
+ item->ident = Qentity;
+ item->start = position;
+ item->end = position + length;
+ item->info = NULL;
+ item->combine = NULL;
+ item->override = False;
+ item->replace = (XtPointer)parser->entity;
+ item->child = item->next = NULL;
+
+ it = head->child;
+
+ item->parent = head;
+ if (it == NULL)
+ head->child = item;
+ else {
+ while (it->next)
+ it = it->next;
+ it->next = item;
+ }
+
+ return;
+ }
+ XawTextSourceAddEntity(parser->source, 0,
+ XAW_TENTF_READ | XAW_TENTF_REPLACE,
+ (XtPointer)parser->entity,
+ position, length, Qentity);
+ }
+
+ segment.x1 = position;
+ segment.x2 = position + length;
+ (void)XmuScanlineOrSegment(parser->mask, &segment);
+ }
+}
+
+static void
+Html_ParseTag(Html_Parser *parser)
+{
+ int ch, sz;
+ char buf[32];
+ Html_TagInfo *info;
+ Html_Item *item = NULL;
+ XawTextPosition offset = parser->offset - 1;
+
+ switch (Html_Peek(parser)) {
+ case '!':
+ (void)Html_Get(parser); /* eat `!' */
+ if (Html_Peek(parser) == '-') {
+ /* comment */
+ (void)Html_Get(parser); /* eat `-' */
+ if (Html_Peek(parser) == '-') {
+ int count = 0;
+
+ (void)Html_Get(parser);
+ while ((ch = Html_Peek(parser)) != EOF) {
+ if (ch == '>' && count >= 2)
+ break;
+ else if (ch == '-')
+ ++count;
+ else
+ count = 0;
+ (void)Html_Get(parser);
+ }
+ }
+ }
+ break;
+ case '?':
+ break;
+ case '/':
+ (void)Html_Get(parser); /* eat `/' */
+ sz = 0;
+ while (isalnum(Html_Peek(parser)) &&
+ sz <= sizeof(buf) + 1)
+ buf[sz++] = tolower(Html_Get(parser));
+ buf[sz] = '\0';
+ if ((info = Html_GetInfo(buf)) != NULL) {
+ if (parser->head) {
+ Html_Item *it = parser->head;
+
+ while (it) {
+ if (it->info == info)
+ break;
+ it = it->parent;
+ }
+
+ if (it) {
+ if (it == parser->head)
+ parser->head->end = offset;
+ else {
+ it->end = offset;
+ do {
+ parser->head->end = offset;
+ parser->head = parser->head->parent;
+ } while (parser->head != it);
+ }
+ if (parser->head->parent)
+ parser->head = parser->head->parent;
+ else
+ parser->head = parser->item;
+ }
+ }
+ }
+ break;
+ default:
+ sz = 0;
+ while (isalnum(Html_Peek(parser)) &&
+ sz <= sizeof(buf) + 1)
+ buf[sz++] = tolower(Html_Get(parser));
+ buf[sz] = '\0';
+ if ((info = Html_GetInfo(buf)) != NULL) {
+ if (info->end == False) {
+ if (info->ident == Qli)
+ parser->quark = Qli;
+ if (!info->para)
+ break; /* no more processing required */
+ }
+ item = XtNew(Html_Item);
+ item->info = info;
+ item->ident = item->info->ident;
+ item->combine = NULL;
+ item->override = False;
+ item->start = item->end = -1;
+ if (info->ident == Qol)
+ item->li = 1;
+ else
+ item->li = 0;
+ item->parent = item->child = item->next = NULL;
+ if (parser->item == NULL)
+ parser->item = parser->head = item;
+ else if (parser->head->end == -1) {
+ if (parser->head->info != item->info || info->nest) {
+ Html_Item *it = parser->head;
+
+ /* first, see if we need to close a long list of tags */
+ if (info->ident == Qdd) {
+ if (parser->head &&
+ parser->head->info->ident == Qdt) {
+ parser->head->end = offset;
+ parser->head = parser->head->parent;
+ }
+ }
+ else if (info->ident == Qdt) {
+ if (parser->head &&
+ parser->head->info->ident == Qdd) {
+ parser->head->end = offset;
+ parser->head = parser->head->parent;
+ }
+ }
+ else if (!info->nest) {
+ while (it) {
+ if (it->info == info || it->info->end)
+ break;
+ it = it->parent;
+ }
+ if (it) {
+ /* close the items */
+ while (parser->head != it) {
+ if (parser->head->info->ident == Qpre)
+ --parser->pre;
+ parser->head->end = offset;
+ parser->head = parser->head->parent;
+ }
+ }
+ }
+
+ /* add child item */
+ it = parser->head->child;
+
+ item->parent = parser->head;
+ if (it == NULL)
+ parser->head->child = item;
+ else {
+ while (it->next)
+ it = it->next;
+ it->next = item;
+ }
+ parser->head = item;
+ }
+ else {
+ /* close the `head' item and start a new one */
+ Html_Item *it;
+
+ parser->head->end = offset;
+ if (parser->head->parent)
+ parser->head = parser->head->parent;
+ else
+ parser->head = parser->item;
+
+ if ((it = parser->head->child) != NULL) {
+ item->parent = parser->head;
+ while (it->next)
+ it = it->next;
+ it->next = item;
+ parser->head = item;
+ }
+ else {
+ parser->head->child = item;
+ parser->head = item;
+ }
+ }
+ }
+ else {
+ /* this is not common, but handle it */
+ Html_Item *it = parser->item;
+
+ while (it->next)
+ it = it->next;
+ it->next = item;
+ parser->head = item;
+ }
+ if (info->parse_args)
+ (info->parse_args)(parser, item);
+ }
+ break;
+ }
+
+ /* skip anything not processed */
+ while ((ch = Html_Peek(parser)) != '>' && ch != EOF)
+ (void)Html_Get(parser);
+ if (item && item->start == -1)
+ item->start = parser->offset + 1;
+}
+
+/* tags */
+static int
+Html_Parse2(Html_Parser *parser)
+{
+ int ch;
+
+ for (;;) {
+ if ((ch = Html_Get(parser)) == '<') {
+ parser->end = parser->offset - 1;
+ Html_Commit(parser);
+ parser->quark = Qhide;
+ parser->start = parser->end;
+
+ Html_ParseTag(parser);
+
+ (void)Html_Get(parser); /* eat `>' */
+ parser->end = parser->offset;
+ Html_Commit(parser);
+ }
+ else
+ return (ch);
+ }
+ /*NOTREACHED*/
+}
+
+/* entities */
+static int
+Html_Parse1(Html_Parser *parser)
+{
+ static XawTextBlock *entities[256];
+ static char chars[256];
+ int ch;
+
+ for (;;) {
+ if ((ch = Html_Parse2(parser)) == EOF)
+ return (EOF);
+
+ if (ch == '&') {
+ unsigned char idx = '?';
+ char buf[32];
+ int sz = 0;
+
+ /* the string comparisons need a big optmization! */
+ parser->end = parser->offset - 1;
+ Html_Commit(parser);
+ parser->start = parser->end;
+ while ((ch = Html_Peek(parser)) != ';'
+ && ch != EOF && !isspace(ch)) {
+ ch = Html_Get(parser);
+ if (sz + 1 <= sizeof(buf))
+ buf[sz++] = ch;
+ }
+ buf[sz] = '\0';
+ if (ch == ';')
+ (void)Html_Get(parser);
+ if (sz == 0)
+ idx = '&';
+ else if (strcasecmp(buf, "lt") == 0)
+ idx = '<';
+ else if (strcasecmp(buf, "gt") == 0)
+ idx = '>';
+ else if (strcasecmp(buf, "nbsp") == 0)
+ idx = ' ';
+ else if (strcasecmp(buf, "amp") == 0)
+ idx = '&';
+ else if (strcasecmp(buf, "quot") == 0)
+ idx = '"';
+ else if (*buf == '#') {
+ if (sz == 1)
+ idx = '#';
+ else {
+ char *tmp;
+
+ idx = strtol(buf + 1, &tmp, 10);
+ if (*tmp)
+ idx = '?';
+ }
+ }
+ else if (strcmp(buf + 1, "acute") == 0) {
+ switch (*buf) {
+ case 'a': idx = 'á'; break; case 'e': idx = 'é'; break;
+ case 'i': idx = 'í'; break; case 'o': idx = 'ó'; break;
+ case 'u': idx = 'ú'; break; case 'A': idx = 'Á'; break;
+ case 'E': idx = 'É'; break; case 'I': idx = 'Í'; break;
+ case 'O': idx = 'Ó'; break; case 'U': idx = 'Ú'; break;
+ case 'y': idx = 'ý'; break; case 'Y': idx = 'Ý'; break;
+ }
+ }
+ else if (strcmp(buf + 1, "grave") == 0) {
+ switch (*buf) {
+ case 'a': idx = 'à'; break; case 'e': idx = 'è'; break;
+ case 'i': idx = 'ì'; break; case 'o': idx = 'ò'; break;
+ case 'u': idx = 'ù'; break; case 'A': idx = 'À'; break;
+ case 'E': idx = 'È'; break; case 'I': idx = 'Ì'; break;
+ case 'O': idx = 'Ò'; break; case 'U': idx = 'Ù'; break;
+ }
+ }
+ else if (strcmp(buf + 1, "tilde") == 0) {
+ switch (*buf) {
+ case 'a': idx = 'ã'; break; case 'o': idx = 'õ'; break;
+ case 'n': idx = 'ñ'; break; case 'A': idx = 'Ã'; break;
+ case 'O': idx = 'Õ'; break; case 'N': idx = 'Ñ'; break;
+ }
+ }
+ else if (strcmp(buf + 1, "circ") == 0) {
+ switch (*buf) {
+ case 'a': idx = 'â'; break; case 'e': idx = 'ê'; break;
+ case 'i': idx = 'î'; break; case 'o': idx = 'ô'; break;
+ case 'u': idx = 'û'; break; case 'A': idx = 'Â'; break;
+ case 'E': idx = 'Ê'; break; case 'I': idx = 'Î'; break;
+ case 'O': idx = 'Ô'; break; case 'U': idx = 'Û'; break;
+ }
+ }
+ else if (strcmp(buf + 1, "uml") == 0) {
+ switch (*buf) {
+ case 'a': idx = 0xe4;break; case 'e': idx = 0xeb;break;
+ case 'i': idx = 0xef;break; case 'o': idx = 0xf6;break;
+ case 'u': idx = 'ü'; break; case 'A': idx = 0xc4;break;
+ case 'E': idx = 0xcb;break; case 'I': idx = 0xfc;break;
+ case 'O': idx = 0xd6;break; case 'U': idx = 'Ü'; break;
+ case 'y': idx = 0xff;break;
+ }
+ }
+ else if (strcmp(buf + 1, "cedil") == 0) {
+ switch (*buf) {
+ case 'c': idx = 'ç'; break; case 'C': idx = 'Ç'; break;
+ }
+ }
+ else if (strcmp(buf + 1, "slash") == 0) {
+ switch (*buf) {
+ case 'o': idx = 0xf8; break;case 'O': idx = 0xd8; break;
+ }
+ }
+ else if (strcmp(buf + 1, "ring") == 0) {
+ switch (*buf) {
+ case 'a': idx = 0xe5; break;case 'A': idx = 0xc5; break;
+ }
+ }
+ else if (strcasecmp(buf, "iexcl") == 0)
+ idx = 0xa1;
+ else if (strcasecmp(buf, "cent") == 0)
+ idx = 0xa2;
+ else if (strcasecmp(buf, "pound") == 0)
+ idx = 0xa3;
+ else if (strcasecmp(buf, "curren") == 0)
+ idx = 0xa4;
+ else if (strcasecmp(buf, "yen") == 0)
+ idx = 0xa5;
+ else if (strcasecmp(buf, "brvbar") == 0)
+ idx = 0xa6;
+ else if (strcasecmp(buf, "sect") == 0)
+ idx = 0xa7;
+ else if (strcasecmp(buf, "uml") == 0)
+ idx = 0xa8;
+ else if (strcasecmp(buf, "copy") == 0)
+ idx = 0xa9;
+ else if (strcasecmp(buf, "ordf") == 0)
+ idx = 'ª';
+ else if (strcasecmp(buf, "laquo") == 0)
+ idx = 0xab;
+ else if (strcasecmp(buf, "not") == 0)
+ idx = 0xac;
+ else if (strcasecmp(buf, "shy") == 0)
+ idx = 0xad;
+ else if (strcasecmp(buf, "reg") == 0)
+ idx = 0xae;
+ else if (strcasecmp(buf, "macr") == 0)
+ idx = 0xaf;
+ else if (strcasecmp(buf, "deg") == 0)
+ idx = '°';
+ else if (strcasecmp(buf, "plusmn") == 0)
+ idx = 0xb1;
+ else if (strcasecmp(buf, "sup2") == 0)
+ idx = '²';
+ else if (strcasecmp(buf, "sup3") == 0)
+ idx = '³';
+ else if (strcasecmp(buf, "acute") == 0)
+ idx = 0xb4;
+ else if (strcasecmp(buf, "micro") == 0)
+ idx = 0xb5;
+ else if (strcasecmp(buf, "para") == 0)
+ idx = 0xb6;
+ else if (strcasecmp(buf, "middot") == 0)
+ idx = 0xb7;
+ else if (strcasecmp(buf, "cedil") == 0)
+ idx = 0xb8;
+ else if (strcasecmp(buf, "supl") == 0)
+ idx = '¹';
+ else if (strcasecmp(buf, "ordm") == 0)
+ idx = 'º';
+ else if (strcasecmp(buf, "raquo") == 0)
+ idx = 0xbb;
+ else if (strcasecmp(buf, "frac14") == 0)
+ idx = 0xbc;
+ else if (strcasecmp(buf, "frac12") == 0)
+ idx = 0xbd;
+ else if (strcasecmp(buf, "frac34") == 0)
+ idx = 0xbe;
+ else if (strcasecmp(buf, "iquest") == 0)
+ idx = 0xbf;
+ else if (strcasecmp(buf, "AElig") == 0)
+ idx = 0xc6;
+ else if (strcasecmp(buf, "ETH") == 0)
+ idx = 0xd0;
+ else if (strcasecmp(buf, "THORN") == 0)
+ idx = 0xde;
+ else if (strcasecmp(buf, "szlig") == 0)
+ idx = 0xdf;
+ else if (strcasecmp(buf, "aelig") == 0)
+ idx = 0xe6;
+ else if (strcasecmp(buf, "eth") == 0)
+ idx = 0xf0;
+ else if (strcasecmp(buf, "thorn") == 0)
+ idx = 0xfe;
+
+ parser->quark = Qentity;
+ if (entities[idx] == NULL) {
+ entities[idx] = XtNew(XawTextBlock);
+ entities[idx]->firstPos = 0;
+ entities[idx]->length = 1;
+ entities[idx]->ptr = chars + idx;
+ entities[idx]->format = FMT8BIT;
+ chars[idx] = idx;
+ }
+ parser->entity = entities[idx];
+ parser->end = parser->offset;
+ Html_Commit(parser);
+ parser->start = parser->end;
+ }
+ }
+ /*NOTREACHED*/
+}
+
+/************************************************************************/
+/* FORMAT */
+/************************************************************************/
+static int
+Html_Put(Html_Parser *parser, int ch)
+{
+ if (ch != '\r') {
+ if (parser->replace.length % 4096 == 0)
+ parser->replace.ptr = XtRealloc(parser->replace.ptr,
+ parser->replace.length + 4096);
+ parser->replace.ptr[parser->replace.length++] = ch;
+ }
+
+ return (ch);
+}
+
+static void
+Html_Puts(Html_Parser *parser, char *str)
+{
+ int len = strlen(str);
+
+ if (parser->replace.length % 4096 == 0 ||
+ parser->replace.length + len > parser->replace.length +
+ (4096 - (parser->replace.length % 4096)))
+ parser->replace.ptr = XtRealloc(parser->replace.ptr,
+ parser->replace.length + 4096);
+ memcpy(parser->replace.ptr + parser->replace.length, str, len);
+ parser->replace.length += len;
+}
+
+static void
+Html_FormatTag(Html_Parser *parser)
+{
+ int ch = 0, sz = 0;
+ char buf[32];
+ Html_TagInfo *info = NULL;
+
+ switch (Html_Peek(parser)) {
+ case '!':
+ Html_Put(parser, '<');
+ Html_Put(parser, Html_Get(parser)); /* eat `!' */
+ if (Html_Peek(parser) == '-') {
+ /* comment */
+ Html_Put(parser, Html_Get(parser)); /* eat `-' */
+ if (Html_Peek(parser) == '-') {
+ int count = 0;
+
+ Html_Put(parser, Html_Get(parser));
+ while ((ch = Html_Peek(parser)) != EOF) {
+ if (ch == '>' && count >= 2)
+ break;
+ else if (ch == '-')
+ ++count;
+ else
+ count = 0;
+ Html_Put(parser, Html_Get(parser));
+ }
+ (void)Html_Get(parser); /* eat `>' */
+ Html_Put(parser, '>');
+ return;
+ }
+ }
+ break;
+ case '?':
+ Html_Put(parser, '<');
+ break;
+ case '/':
+ (void)Html_Get(parser); /* eat `/' */
+ while (isalnum(Html_Peek(parser)) &&
+ sz <= sizeof(buf) + 1)
+ buf[sz++] = ch = tolower(Html_Get(parser));
+ buf[sz] = '\0';
+ if ((info = Html_GetInfo(buf)) != NULL && info->adnl) {
+ if (info->ident == Qpre && parser->pre) {
+ if (--parser->pre == 0)
+ parser->column = 0;
+ }
+ parser->quark = Qetag;
+ parser->spc = True;
+ if (info->ident == Qp) {
+ while ((ch = Html_Peek(parser) != '>' && ch != EOF))
+ (void)Html_Get(parser);
+ (void)Html_Get(parser); /* eat '>' */
+ return;
+ }
+ }
+ else if (info) {
+ if (info->ident == Qol || info->ident == Qul) {
+ if (parser->list && --parser->list == 0 &&
+ parser->desc == 0) {
+ parser->quark = Qetag;
+ Html_Put(parser, '\n');
+ ++parser->adnl;
+ parser->column = 0;
+ }
+ }
+ else if (info->ident == Qdl) {
+ if (parser->desc && --parser->desc == 0 &&
+ parser->list == 0) {
+ parser->quark = Qetag;
+ Html_Put(parser, '\n');
+ ++parser->adnl;
+ parser->column = 0;
+ }
+ }
+ }
+ Html_Puts(parser, "</");
+ Html_Puts(parser, buf);
+ break;
+ default:
+ while (isalnum(Html_Peek(parser)) &&
+ sz <= sizeof(buf) + 1)
+ buf[sz++] = tolower(Html_Get(parser));
+ buf[sz] = '\0';
+ if ((info = Html_GetInfo(buf)) != NULL && info->adnl) {
+ if (info->ident == Qpre)
+ ++parser->pre;
+ if (parser->quark != Qtag) {
+ if (parser->adnl < 2) {
+ Html_Puts(parser, parser->adnl ? pnl : nlpnl);
+ parser->adnl = 2;
+ parser->spc = True;
+ parser->column = 0;
+ }
+ }
+ parser->quark = Qtag;
+ if (info->ident == Qp) {
+ while ((ch = Html_Peek(parser) != '>' && ch != EOF))
+ (void)Html_Get(parser);
+ (void)Html_Get(parser); /* eat '>' */
+ return;
+ }
+ }
+ else if (info) {
+ if (info->ident == Qol || info->ident == Qul) {
+ if (++parser->list == 1 && !parser->desc) {
+ if (parser->adnl < 2) {
+ Html_Puts(parser, parser->adnl ? pnl : nlpnl);
+ parser->adnl = 2;
+ parser->column = 0;
+ }
+ }
+ else if (parser->adnl == 0) {
+ Html_Put(parser, '\n');
+ parser->adnl = 1;
+ parser->column = 0;
+ }
+ parser->spc = True;
+ }
+ else if (info->ident == Qli) {
+ if (parser->adnl == 0) {
+ Html_Put(parser, '\n');
+ parser->adnl = 1;
+ parser->column = 0;
+ }
+ }
+
+ else if (info->ident == Qdl) {
+ if (++parser->desc == 1 && !parser->list) {
+ if (parser->adnl < 2) {
+ Html_Puts(parser, parser->adnl ? pnl : nlpnl);
+ parser->adnl = 2;
+ parser->column = 0;
+ }
+ }
+ else if (parser->adnl == 0) {
+ Html_Put(parser, '\n');
+ parser->adnl = 1;
+ parser->column = 0;
+ }
+ parser->spc = True;
+ }
+ else if (info->ident == Qdd) {
+ if (parser->desc == 0) {
+ if (parser->adnl < 2) {
+ Html_Puts(parser, parser->adnl ? pnl : nlpnl);
+ parser->adnl = 2;
+ parser->column = 0;
+ }
+ }
+ else if (parser->adnl == 0) {
+ Html_Put(parser, '\n');
+ parser->adnl = 1;
+ parser->column = 0;
+ }
+ parser->spc = True;
+ }
+ else if (info->ident == Qdt) {
+ if (parser->adnl == 0) {
+ Html_Put(parser, '\n');
+ parser->adnl = 1;
+ parser->spc = True;
+ parser->column = 0;
+ }
+ }
+ }
+ Html_Put(parser, '<');
+ Html_Puts(parser, buf);
+ break;
+ }
+
+ sz = 0;
+ while ((ch = Html_Peek(parser)) != '>' && ch != EOF) {
+ if (isspace(ch)) {
+ (void)Html_Get(parser);
+ ++sz;
+ continue;
+ }
+ else if (sz) {
+ Html_Put(parser, ' ');
+ sz = 0;
+ }
+ Html_Put(parser, Html_Get(parser));
+ }
+ Html_Put(parser, Html_Get(parser)); /* eat `>' */
+ if (info && info->ident == Qbr) {
+ ++parser->adnl;
+ parser->spc = True;
+ Html_Put(parser, '\n');
+ parser->quark = info->ident;
+ parser->column = 0;
+ }
+}
+
+/* tags */
+static int
+Html_Format3(Html_Parser *parser)
+{
+ int ch;
+
+ for (;;) {
+ if ((ch = Html_Get(parser)) == '<') {
+ if (parser->quark == Qspace && parser->spc == False) {
+ Html_Put(parser, ' ');
+ parser->spc = True;
+ }
+
+/* parser->quark = Qhide;*/
+ Html_FormatTag(parser);
+ }
+ else
+ return (ch);
+ }
+ /*NOTREACHED*/
+}
+
+/* entities */
+static int
+Html_Format2(Html_Parser *parser)
+{
+ int ch;
+
+ for (ch = Html_Format3(parser); ch == '&'; ch = Html_Format3(parser)) {
+ Html_Put(parser, '&');
+ while ((ch = Html_Peek(parser)) != ';') {
+ if (isspace(ch) || ch == EOF)
+ break;
+ Html_Put(parser, Html_Get(parser));
+ }
+ if (ch != EOF)
+ Html_Put(parser, Html_Get(parser));
+ else
+ break;
+ if (parser->pre)
+ ++parser->column;
+ }
+
+ return (ch);
+}
+
+/* spaces */
+static int
+Html_Format1(Html_Parser *parser)
+{
+ int ch;
+
+ for (;;) {
+ if ((ch = Html_Format2(parser)) == EOF)
+ return (ch);
+
+ if (parser->quark == Qetag) {
+ if (parser->adnl < 2) {
+ Html_Puts(parser, parser->adnl ? pnl : nlpnl);
+ parser->adnl = 2;
+ parser->spc = True;
+ }
+ }
+ else if (parser->quark == Qspace && parser->spc == False) {
+ Html_Put(parser, ' ');
+ parser->spc = True;
+ }
+
+ if (!parser->pre && isspace(ch))
+ parser->quark = Qspace;
+ else {
+ if (parser->pre) {
+ if (parser->spc) {
+ /* did not yet see any non space character */
+ if (isspace(ch)) {
+ if (ch == '\n') {
+ parser->column = 0;
+ parser->spc = False;
+ parser->adnl = 1;
+ }
+ else if (ch == '\t')
+ parser->column += 8 - (parser->column % 8);
+ else
+ ++parser->column;
+ continue;
+ }
+ else {
+ int column = parser->column;
+
+ while (column-- > 0)
+ Html_Put(parser, ' ');
+ parser->spc = False;
+ parser->adnl = 0;
+ }
+ }
+ else if (ch == '\n') {
+ ++parser->adnl;
+ parser->column = 0;
+ }
+ else if (ch == '\t') {
+ int column = parser->column + (8 - (parser->column % 8));
+
+ parser->adnl = 0;
+ while (parser->column < column) {
+ Html_Put(parser, ' ');
+ ++parser->column;
+ }
+ continue;
+ }
+ else {
+ parser->adnl = 0;
+ ++parser->column;
+ }
+ }
+ else
+ parser->adnl = 0;
+ Html_Put(parser, ch);
+ parser->quark = Qdefault;
+ parser->spc = False;
+ }
+ }
+}
+
+/************************************************************************/
+/* ARGUMENTS */
+/************************************************************************/
+static void
+Html_AArgs(Html_Parser *parser, Html_Item *item)
+{
+ int ch, sz;
+ char buf[32];
+
+ /*CONSTCOND*/
+ while (True) {
+ sz = 0;
+ while ((ch = Html_Peek(parser)) != '>' && ch != EOF) {
+ if (isalnum(ch))
+ break;
+ else
+ (void)Html_Get(parser);
+ }
+
+ if (ch == '>' || ch == EOF)
+ return;
+ buf[sz++] = tolower(Html_Get(parser));
+ while ((ch = Html_Peek(parser)) != '>' && ch != EOF)
+ if (isalnum(ch))
+ buf[sz++] = tolower(Html_Get(parser));
+ else
+ break;
+ buf[sz] = '\0';
+ if (strcmp(buf, "href") == 0) {
+ item->combine = XawTextSinkCopyProperty(XawTextGetSink(text),
+ item->info->ident);
+ item->override = True;
+ item->combine->xlfd_mask = 0L;
+ item->combine->mask = XAW_TPROP_UNDERLINE | XAW_TPROP_FOREGROUND;
+ item->combine->foreground = parser->alink;
+ return;
+ }
+ while ((ch = Html_Peek(parser)) != '>' && ch != EOF) {
+ if (isspace(ch))
+ break;
+ else
+ (void)Html_Get(parser);
+ }
+ }
+}
+
+static void
+Html_FontArgs(Html_Parser *parser, Html_Item *item)
+{
+ int ch, sz;
+ char name[32], value[256], xlfd[128];
+
+ item->combine = XawTextSinkCopyProperty(XawTextGetSink(text),
+ Qdefault);
+ item->override = True;
+ item->combine->mask = item->combine->xlfd_mask = 0L;
+
+ /*CONSTCOND*/
+ while (True) {
+ /* skip white spaces */
+ while ((ch = Html_Peek(parser)) != '>' && ch != EOF) {
+ if (isalnum(ch))
+ break;
+ else
+ (void)Html_Get(parser);
+ }
+
+ if (ch == '>' || ch == EOF)
+ return;
+
+ /* read option name */
+ sz = 0;
+ name[sz++] = tolower(Html_Get(parser));
+ while ((ch = Html_Peek(parser)) != '>' && ch != EOF)
+ if (isalnum(ch) && sz + 1 <= sizeof(name))
+ name[sz++] = tolower(Html_Get(parser));
+ else
+ break;
+ name[sz] = '\0';
+
+ if (ch != '=')
+ continue;
+ (void)Html_Get(parser); /* skip `=' */
+ if (Html_Peek(parser) == '"')
+ (void)Html_Get(parser);
+
+ sz = 0;
+ while ((ch = Html_Peek(parser)) != '>' && ch != EOF) {
+ if (!isspace(ch) && sz + 1 <= sizeof(value))
+ value[sz++] = Html_Get(parser);
+ else
+ break;
+ }
+ value[sz] = '\0';
+ if (sz > 0 && value[sz - 1] == '"')
+ value[--sz] = '\0';
+
+ if (strcmp(name, "color") == 0) {
+ XColor color, exact;
+
+ if (XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap,
+ value, &color, &exact)) {
+ item->combine->mask |= XAW_TPROP_FOREGROUND;
+ item->combine->foreground = color.pixel;
+ }
+ }
+ else if (strcmp(name, "face") == 0) {
+ int count = 0;
+ char *ptr, *family, **font_list;
+
+ ptr = value;
+ do {
+ family = ptr;
+ ptr = strchr(ptr, ',');
+ if (ptr)
+ *ptr++ = '\0';
+ XmuSnprintf(xlfd, sizeof(xlfd), "-*-%s-*-*-*-*-*-*-*-*-*-*-*-*",
+ family);
+ font_list = XListFonts(XtDisplay(toplevel), xlfd, 1, &count);
+ if (font_list)
+ XFreeFontNames(font_list);
+ if (count)
+ break;
+ } while (ptr);
+ if (count) {
+ item->combine->xlfd_mask |= XAW_TPROP_FAMILY;
+ item->combine->family = XrmStringToQuark(family);
+ }
+ }
+ else if (strcmp(name, "size") == 0) {
+ int size, sign = 0;
+
+ if (isalnum(*value)) {
+ size = atoi(value);
+ sign = 0;
+ }
+ else {
+ char *str = XrmQuarkToString(item->combine->pixel_size);
+
+ size = str ? atoi(str) : 12;
+ if (*value == '+') {
+ size += atoi(value + 1);
+ sign = 1;
+ }
+ else if (*value == '-') {
+ size -= atoi(value + 1);
+ sign = -1;
+ }
+ }
+
+ if (item->combine->xlfd != NULLQUARK) {
+ int count, ucount, dcount, usize, dsize;
+ char **current, **result, **up, **down;
+
+ current = result = up = down = NULL;
+ /* try to load an appropriate font */
+ XmuSnprintf(value, sizeof(value),
+ "-*-%s-%s-%s-*--%%d-*-*-*-*-*-%s-%s",
+ XrmQuarkToString(item->combine->family),
+ XrmQuarkToString(item->combine->weight),
+ XrmQuarkToString(item->combine->slant),
+ XrmQuarkToString(item->combine->registry),
+ XrmQuarkToString(item->combine->encoding));
+ XmuSnprintf(xlfd, sizeof(xlfd), value,
+ atoi(XrmQuarkToString(item->combine->pixel_size)));
+ current = XListFonts(XtDisplay(toplevel), xlfd, 1, &count);
+ if (count) {
+ ucount = dcount = usize = dsize = 0;
+
+ XmuSnprintf(xlfd, sizeof(xlfd), value, size);
+ result = XListFonts(XtDisplay(toplevel), xlfd, 1, &count);
+ if (count == 0 || strstr(*result, "-0-")) {
+ if (sign <= 0) {
+ sz = dsize = size;
+ while (dcount == 0 && --sz > size - 8 && sz > 1) {
+ XmuSnprintf(xlfd, sizeof(xlfd), value, sz);
+ down = XListFonts(XtDisplay(toplevel), xlfd,
+ 1, &dcount);
+ if (dcount && strstr(*down, "-0-") != NULL) {
+ XFreeFontNames(down);
+ down = NULL;
+ dcount = 0;
+ }
+ }
+ if (dcount)
+ dsize = sz;
+ }
+ if (sign >= 0) {
+ sz = usize = size;
+ while (ucount == 0 && ++sz < size + 8) {
+ XmuSnprintf(xlfd, sizeof(xlfd), value, sz);
+ up = XListFonts(XtDisplay(toplevel), xlfd,
+ 1, &ucount);
+ if (ucount && strstr(*up, "-0-") != NULL) {
+ XFreeFontNames(up);
+ up = NULL;
+ ucount = 0;
+ }
+ }
+ if (ucount)
+ usize = sz;
+ }
+ if (ucount && dcount)
+ size = size - dsize < usize - size ? dsize : usize;
+ else if (ucount)
+ size = usize;
+ else if (dcount)
+ size = dsize;
+ }
+ if (current)
+ XFreeFontNames(current);
+ if (result)
+ XFreeFontNames(result);
+ if (up)
+ XFreeFontNames(up);
+ if (down)
+ XFreeFontNames(down);
+ }
+ }
+
+ XmuSnprintf(value, sizeof(value), "%d", size);
+ item->combine->xlfd_mask |= XAW_TPROP_PIXELSIZE;
+ item->combine->pixel_size = XrmStringToQuark(value);
+ }
+
+ while ((ch = Html_Peek(parser)) != '>' && ch != EOF) {
+ if (isspace(ch))
+ break;
+ else
+ (void)Html_Get(parser);
+ }
+ }
+}
diff --git a/hw/xfree86/utils/xorgcfg/help.h b/hw/xfree86/utils/xorgcfg/help.h
new file mode 100644
index 000000000..f03e01b14
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/help.h
@@ -0,0 +1,42 @@
+/*
+ * 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/help.h,v 1.1 2000/06/13 23:15:51 dawes Exp $
+ */
+
+/* help string definitions */
+#define HELP_DEVICES "helpDevices" /* Configure Layout */
+#define HELP_SCREEN "helpScreen" /* Configure Screen */
+#define HELP_MODELINE "helpModeline" /* Configure Modeline */
+#define HELP_ACCESSX "helpAccessX" /* Configure AccessX */
+
+/*
+ * Prototypes
+ */
+void Help(char*);
+void HelpCancelAction(Widget, XEvent*, String*, Cardinal*);
diff --git a/hw/xfree86/utils/xorgcfg/interface.c b/hw/xfree86/utils/xorgcfg/interface.c
new file mode 100644
index 000000000..68a1873ed
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/interface.c
@@ -0,0 +1,2280 @@
+/*
+ * 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/interface.c,v 1.37 2002/10/21 04:18:36 paulo Exp $
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Composite.h>
+#include <X11/Shell.h>
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/Simple.h>
+#include <X11/Xaw/Paned.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/MenuButton.h>
+#include <X11/Xaw/SmeBSB.h>
+#include <X11/Xaw/SmeLine.h>
+#include <X11/Xaw/SimpleMenP.h>
+#include <X11/Xaw/Dialog.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include "xf86config.h"
+#include "mouse-cfg.h"
+#include "keyboard-cfg.h"
+#include "card-cfg.h"
+#include "monitor-cfg.h"
+#include "screen-cfg.h"
+#include "screen.h"
+#include "cards.h"
+#include "options.h"
+#include "vidmode.h"
+#include "help.h"
+#include "stubs.h"
+
+#define randomize() srand((unsigned)time((time_t*)NULL))
+#ifdef PROJECT_ROOT
+#define DefaultXFree86Dir PROJECT_ROOT
+#else
+#define DefaultXFree86Dir "/usr/X11R6"
+#endif
+
+/*
+ * Prototypes
+ */
+void DrawCables(void);
+static void DrawCable(Display*, Window, int, int, int, int);
+static void ComputerEventHandler(Widget, XtPointer, XEvent*, Boolean*);
+void SelectDeviceAction(Widget, XEvent*, String*, Cardinal*);
+void MoveDeviceAction(Widget, XEvent*, String*, Cardinal*);
+void UnselectDeviceAction(Widget, XEvent*, String*, Cardinal*);
+void RenameLayoutAction(Widget, XEvent*, String*, Cardinal*);
+void DevicePopupMenu(Widget, XEvent*, String*, Cardinal*);
+void DevicePopdownMenu(Widget, XEvent*, String*, Cardinal*);
+void AddDeviceCallback(Widget, XtPointer, XtPointer);
+void QuitCallback(Widget, XtPointer, XtPointer);
+void SmeConfigureDeviceCallback(Widget, XtPointer, XtPointer);
+void ConfigureDeviceCallback(Widget, XtPointer, XtPointer);
+void EnableDeviceCallback(Widget, XtPointer, XtPointer);
+void DisableDeviceCallback(Widget, XtPointer, XtPointer);
+void RemoveDeviceCallback(Widget, XtPointer, XtPointer);
+void InitializeDevices(void);
+void SetConfigModeCallback(Widget, XtPointer, XtPointer);
+void SelectLayoutCallback(Widget, XtPointer, XtPointer);
+void DefaultLayoutCallback(Widget, XtPointer, XtPointer);
+void RemoveLayoutCallback(Widget, XtPointer, XtPointer);
+void OptionsCallback(Widget, XtPointer, XtPointer);
+xf86cfgDevice *AddDevice(int, XtPointer, int, int);
+static Bool AskConfig(void);
+void WriteConfigAction(Widget, XEvent*, String*, Cardinal*);
+static void ScreenSetup(Bool);
+void QuitAction(Widget, XEvent*, String*, Cardinal*);
+void PopdownErrorCallback(Widget, XtPointer, XtPointer);
+static void ErrorCancelAction(Widget, XEvent*, String*, Cardinal*);
+static void QuitCancelAction(Widget, XEvent*, String*, Cardinal*);
+static void HelpCallback(Widget, XtPointer, XtPointer);
+void UpdateMenuDeviceList(int);
+
+extern void AccessXConfigureStart(void);
+extern void AccessXConfigureEnd(void);
+extern void CloseAccessXAction(Widget, XEvent*, String*, Cardinal*);
+
+#ifdef HAS_NCURSES
+extern void TextMode(void);
+#endif
+
+static void Usage(void);
+
+/*
+ * Initialization
+ */
+Widget toplevel, work, config, layout, layoutsme, layoutp, topMenu;
+XtAppContext appcon;
+
+Pixmap menuPixmap;
+
+char *XF86Config_path = NULL;
+char *XF86Module_path = NULL;
+char *XFree86_path = NULL;
+char *XF86Font_path = NULL;
+char *XF86RGB_path = NULL;
+char *XkbConfig_path = NULL;
+char *XFree86Dir;
+static char XF86Config_path_static[1024];
+static char XkbConfig_path_static[1024];
+Bool xf86config_set = False;
+
+int textmode = False;
+#ifdef USE_MODULES
+int nomodules = False;
+#endif
+int noverify = False;
+
+xf86cfgComputer computer;
+xf86cfgDevice cpu_device;
+Cursor no_cursor;
+static Widget device, layoutm, popup, commands;
+static int xpos, ypos;
+int sxpos, sypos;
+static char no_cursor_data[] = { 0,0,0,0, 0,0,0,0 };
+static GC cablegc, cablegcshadow;
+Atom wm_delete_window;
+static Bool config_set = False;
+static Widget mouseSme, mouseMenu, keyboardSme, keyboardMenu,
+ cardSme, cardMenu, monitorSme, monitorMenu;
+
+int config_mode = CONFIG_LAYOUT;
+
+static XtActionsRec actions[] = {
+ {"filter-card", CardFilterAction},
+ {"select-device", SelectDeviceAction},
+ {"move-device", MoveDeviceAction},
+ {"unselect-device", UnselectDeviceAction},
+ {"device-popup", DevicePopupMenu},
+ {"device-popdown", DevicePopdownMenu},
+ {"rename-layout", RenameLayoutAction},
+ {"write-config", WriteConfigAction},
+ {"quit", QuitAction},
+ {"vidmode-restore", VidmodeRestoreAction},
+ {"config-cancel", ConfigCancelAction},
+ {"options-cancel", OptionsCancelAction},
+ {"error-cancel", ErrorCancelAction},
+ {"quit-cancel", QuitCancelAction},
+ {"addmode-cancel", CancelAddModeAction},
+ {"accessx-close", CloseAccessXAction},
+ {"testmode-cancel", CancelTestModeAction},
+ {"help-close", HelpCancelAction},
+ {"expert-close", ExpertCloseAction},
+#ifdef USE_MODULES
+ {"module-options-close", ModuleOptionsCancelAction},
+#endif
+};
+
+static char *device_names[] = {
+/* MOUSE */
+ "mouse",
+/* KEYBOARD */
+ "keyboard",
+/* CARD */
+ "card",
+/* MONITOR */
+ "monitor",
+/* SCREEN */
+ "screen",
+};
+
+static XtResource appResources[] = {
+#if 0
+ {"xf86config", "XF86Config", XtRString, sizeof(char*),
+ 0, XtRString, "/etc/X11/XF86Config"},
+#endif
+ {"menuBitmap", "MenuBitmap", XtRString, sizeof(char*),
+ 0, XtRString, "menu10"},
+};
+
+static void
+Usage(void)
+{
+ fprintf(stderr,
+"Usage:\n"
+" xf86cfg [-option ...]\n"
+"\n"
+"Options:\n"
+" -xf86config <XF86Config> Alternate configuration file.\n"
+" -modulepath <module-path> XFree86 modules location.\n"
+" -serverpath <server-path> X server to start (if $DISPLAY is not defined).\n"
+" -fontpath <font-path> Font path for fonts.\n"
+" -rgbpath <rgb-path> Where the rgb.txt file is located.\n"
+#ifdef HAS_NCURSES
+" -textmode Use this option for the text only interface.\n"
+#endif
+#ifdef USE_MODULES
+" -nomodules Use this option if xf86cfg is slow to start.\n"
+" -verbose <number> Verbosity used in the loader (default 1).\n"
+#endif
+" -verify Verify modules/options integrity.\n"
+);
+
+ exit(1);
+}
+
+/*
+ * Implementation
+ */
+int
+main(int argc, char *argv[])
+{
+ Widget pane, hpane, expert, popup, mouse, keyboard, card, monitor;
+ Widget bottom, sme, smemodeline, help, quit, layopt;
+ XColor color, tmp;
+ Pixmap pixmap;
+ XGCValues values;
+ XF86ConfLayoutPtr lay;
+ int i, startedx;
+ char *menuPixmapPath = NULL;
+ XrmValue from, to;
+
+ if ((XFree86Dir = getenv("XWINHOME")) == NULL)
+ XFree86Dir = DefaultXFree86Dir;
+
+ chdir(XFree86Dir);
+
+#ifdef USE_MODULES
+ xf86Verbose = 1;
+#endif
+ noverify = True;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-xf86config") == 0) {
+ if (i + 1 < argc) {
+ XF86Config_path = argv[++i];
+ config_set = True;
+ }
+ } else if (strcmp(argv[i], "-modulepath") == 0) {
+ if (i + 1 < argc)
+ XF86Module_path = argv[++i];
+ } else if (strcmp(argv[i], "-serverpath") == 0) {
+ if (i + 1 < argc)
+ XFree86_path = argv[++i];
+ } else if (strcmp(argv[i], "-fontpath") == 0) {
+ if (i + 1 < argc)
+ XF86Font_path = argv[++i];
+ } else if (strcmp(argv[i], "-rgbpath") == 0) {
+ if (i + 1 < argc)
+ XF86RGB_path = argv[++i];
+ }
+#ifdef HAS_NCURSES
+ else if (strcmp(argv[i], "-textmode") == 0)
+ textmode = True;
+#endif
+#ifdef USE_MODULES
+ else if (strcmp(argv[i], "-nomodules") == 0)
+ nomodules = True;
+ else if (strcmp(argv[i], "-verbose") == 0) {
+ if (i + 1 < argc)
+ xf86Verbose = atoi(argv[++i]);
+ }
+#endif
+ else if (strcmp(argv[i], "-verify") == 0)
+ noverify = False;
+ else
+ Usage();
+ }
+
+#ifdef HAS_NCURSES
+ if (textmode) {
+ TextMode();
+ exit(0);
+ }
+#endif
+
+ startedx = startx();
+ if (XF86Config_path == NULL)
+ XF86Config_path = XtNewString("XF86Config-4");
+ if (XkbConfig_path == NULL) {
+ XmuSnprintf(XkbConfig_path_static, sizeof(XkbConfig_path_static),
+ "%s/%s%s", XFree86Dir, XkbConfigDir, XkbConfigFile);
+ XkbConfig_path = XkbConfig_path_static;
+ }
+ toplevel = XtAppInitialize(&appcon, "XF86Cfg",
+ NULL, 0,
+ &argc, argv,
+ NULL, NULL, 0);
+ if (DPY == NULL)
+ DPY = XtDisplay(toplevel);
+
+ XtGetApplicationResources(toplevel, (XtPointer)&menuPixmapPath,
+ appResources, XtNumber(appResources), NULL, 0);
+ if (menuPixmapPath && strlen(menuPixmapPath)) {
+ from.size = strlen(menuPixmapPath);
+ from.addr = menuPixmapPath;
+ to.size = sizeof(Pixmap);
+ to.addr = (XtPointer)&(menuPixmap);
+ XtConvertAndStore(toplevel, XtRString, &from, XtRBitmap, &to);
+ }
+
+ XtAppAddActions(appcon, actions, XtNumber(actions));
+
+ XawSimpleMenuAddGlobalActions(appcon);
+ XtRegisterGrabAction(DevicePopupMenu, True,
+ ButtonPressMask | ButtonReleaseMask,
+ GrabModeAsync, GrabModeAsync);
+
+ pane = XtCreateManagedWidget("pane", panedWidgetClass,
+ toplevel, NULL, 0);
+ hpane = XtVaCreateManagedWidget("hpane", panedWidgetClass, pane,
+ XtNorientation, XtorientHorizontal, NULL, 0);
+ topMenu = XtCreateManagedWidget("topM", menuButtonWidgetClass,
+ hpane, NULL, 0);
+ expert = XtCreateManagedWidget("expert", commandWidgetClass, hpane, NULL, 0);
+ XtAddCallback(expert, XtNcallback, ExpertCallback, NULL);
+ popup = XtCreatePopupShell("menu", simpleMenuWidgetClass,
+ topMenu, NULL, 0);
+ sme = XtCreateManagedWidget("layout", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(sme, XtNcallback, SetConfigModeCallback,
+ (XtPointer)CONFIG_LAYOUT);
+ sme = XtCreateManagedWidget("screen", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(sme, XtNcallback, SetConfigModeCallback,
+ (XtPointer)CONFIG_SCREEN);
+ smemodeline = XtCreateManagedWidget("modeline", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(smemodeline, XtNcallback, SetConfigModeCallback,
+ (XtPointer)CONFIG_MODELINE);
+ sme = XtCreateManagedWidget("accessx", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(sme, XtNcallback, SetConfigModeCallback,
+ (XtPointer)CONFIG_ACCESSX);
+
+ commands = XtCreateManagedWidget("commands", formWidgetClass,
+ pane, NULL, 0);
+
+ mouse = XtVaCreateManagedWidget("mouse", menuButtonWidgetClass,
+ commands, XtNmenuName, "mouseP", NULL, 0);
+ popup = XtCreatePopupShell("mouseP", simpleMenuWidgetClass,
+ mouse, NULL, 0);
+ sme = XtCreateManagedWidget("new", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(sme, XtNcallback, AddDeviceCallback, (XtPointer)MOUSE);
+ mouseSme = XtCreateManagedWidget("configure", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(mouseSme, XtNcallback, SmeConfigureDeviceCallback,
+ (XtPointer)MOUSE);
+
+ keyboard = XtVaCreateManagedWidget("keyboard", menuButtonWidgetClass,
+ commands, XtNmenuName, "keyboardP", NULL, 0);
+ popup = XtCreatePopupShell("keyboardP", simpleMenuWidgetClass,
+ keyboard, NULL, 0);
+ sme = XtCreateManagedWidget("new", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(sme, XtNcallback, AddDeviceCallback, (XtPointer)KEYBOARD);
+ keyboardSme = XtCreateManagedWidget("configure", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(keyboardSme, XtNcallback, SmeConfigureDeviceCallback,
+ (XtPointer)KEYBOARD);
+
+ card = XtVaCreateManagedWidget("card", menuButtonWidgetClass,
+ commands, XtNmenuName, "cardP", NULL, 0);
+ popup = XtCreatePopupShell("cardP", simpleMenuWidgetClass,
+ card, NULL, 0);
+ sme = XtCreateManagedWidget("new", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(sme, XtNcallback, AddDeviceCallback, (XtPointer)CARD);
+ cardSme = XtCreateManagedWidget("configure", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(cardSme, XtNcallback, SmeConfigureDeviceCallback,
+ (XtPointer)CARD);
+
+ monitor = XtVaCreateManagedWidget("monitor", menuButtonWidgetClass,
+ commands, XtNmenuName, "monitorP", NULL, 0);
+ popup = XtCreatePopupShell("monitorP", simpleMenuWidgetClass,
+ monitor, NULL, 0);
+ sme = XtCreateManagedWidget("new", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(sme, XtNcallback, AddDeviceCallback, (XtPointer)MONITOR);
+ monitorSme = XtCreateManagedWidget("configure", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(monitorSme, XtNcallback, SmeConfigureDeviceCallback,
+ (XtPointer)MONITOR);
+
+ work = XtCreateManagedWidget("work", compositeWidgetClass,
+ pane, NULL, 0);
+
+ bottom = XtCreateManagedWidget("bottom", formWidgetClass,
+ pane, NULL, 0);
+ layoutm = XtCreateManagedWidget("select", menuButtonWidgetClass,
+ bottom, NULL, 0);
+ layout = XtVaCreateManagedWidget("layout", asciiTextWidgetClass,
+ bottom,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ layoutp = XtCreatePopupShell("menu", simpleMenuWidgetClass,
+ bottom, NULL, 0);
+ sme = XtCreateManagedWidget("new", smeBSBObjectClass, layoutp,
+ NULL, 0);
+ XtAddCallback(sme, XtNcallback, SelectLayoutCallback, NULL);
+ help = XtCreateManagedWidget("help", commandWidgetClass,
+ bottom, NULL, 0);
+ XtAddCallback(help, XtNcallback, HelpCallback, NULL);
+ quit = XtCreateManagedWidget("quit", commandWidgetClass,
+ bottom, NULL, 0);
+ XtAddCallback(quit, XtNcallback, QuitCallback, NULL);
+
+ XtRealizeWidget(toplevel);
+ XtRealizeWidget(topMenu);
+
+ pixmap = XCreateBitmapFromData(XtDisplay(toplevel), XtWindow(toplevel),
+ no_cursor_data, 8, 8);
+ XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap, "black",
+ &color, &tmp);
+ no_cursor = XCreatePixmapCursor(XtDisplay(toplevel), pixmap, pixmap,
+ &color, &color, 0, 0);
+
+ XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap, "gray55",
+ &color, &tmp);
+ values.line_width = 3;
+ values.foreground = color.pixel;
+ cablegcshadow = XCreateGC(XtDisplay(toplevel), XtWindow(toplevel),
+ GCForeground | GCLineWidth, &values);
+ XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap, "gray85",
+ &color, &tmp);
+ values.line_width = 1;
+ values.foreground = color.pixel;
+ cablegc = XCreateGC(XtDisplay(toplevel), XtWindow(toplevel),
+ GCForeground | GCLineWidth, &values);
+
+ computer.cpu = XtCreateManagedWidget("cpu", simpleWidgetClass,
+ work, NULL, 0);
+ cpu_device.widget = computer.cpu;
+ cpu_device.type = SERVER;
+
+ XtAddEventHandler(work, ExposureMask, False,
+ ComputerEventHandler, (XtPointer)NULL);
+
+ wm_delete_window = XInternAtom(DPY, "WM_DELETE_WINDOW", False);
+ XSetWMProtocols(DPY, XtWindow(toplevel), &wm_delete_window, 1);
+
+ StartConfig();
+ InitializeDevices();
+ UpdateMenuDeviceList(MOUSE);
+ UpdateMenuDeviceList(KEYBOARD);
+ UpdateMenuDeviceList(CARD);
+ UpdateMenuDeviceList(MONITOR);
+ XtSetSensitive(smemodeline, VideoModeInitialize());
+
+ 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);
+ }
+ SelectLayoutCallback(layoutsme,
+ XF86Config->conf_layout_lst, NULL);
+
+ startaccessx();
+ if (startedx) {
+ switch (fork()) {
+ case 0: {
+ char path[PATH_MAX];
+
+ XmuSnprintf(path, sizeof(path), "%s/bin/twm", XFree86Dir);
+ execl(path, "twm", (void *)NULL);
+ exit(-127);
+ } break;
+ case -1:
+ fprintf(stderr, "Cannot fork.\n");
+ exit(1);
+ break;
+ default:
+ break;
+ }
+ }
+
+#ifdef USE_MODULES
+ if (!nomodules)
+ LoaderInitializeOptions();
+#endif
+
+ /* ReadCardsDatabase() must be called after LoaderInitializeOptions() */
+ ReadCardsDatabase();
+
+ if (!config_set && startedx) {
+ XtFree(XF86Config_path);
+#ifdef XF86CONFIG
+# ifdef XF86CONFIGDIR
+ XF86Config_path = XtNewString(XF86CONFIGDIR "/" XF86CONFIG);
+# else
+ XF86Config_path = XtNewString("/etc/X11/" XF86CONFIG);
+# endif
+#else
+# ifdef XF86CONFIGDIR
+ XF86Config_path = XtNewString(XF86CONFIGDIR "/XF86Config-4");
+# else
+ XF86Config_path = XtNewString("/etc/X11/XF86Config-4");
+# endif
+#endif
+ }
+ XtAppMainLoop(appcon);
+ if (startedx)
+ endx();
+
+ return (0);
+}
+
+static Widget shell_cf;
+static int write_cf, asking_cf;
+static int cf_state = 0;
+#define CF_XF86Config 1
+#define CF_XKBConfig 2
+#define CF_First CF_XF86Config
+#define CF_Last CF_XKBConfig
+
+/*ARGSUSED*/
+static void
+WriteConfig(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ asking_cf = 0;
+ XtPopdown(shell_cf);
+ write_cf = (long)user_data;
+}
+
+/*ARGSUSED*/
+void
+QuitCancelAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+ WriteConfig(w, (XtPointer)-1, NULL);
+}
+
+/*ARGSUSED*/
+void
+WriteConfigAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ WriteConfig(w, (XtPointer)True, NULL);
+}
+
+static Bool
+AskConfig(void)
+{
+ static Widget dialog;
+
+ if (shell_cf == NULL) {
+ Arg args[1];
+ char *l, *label;
+ int len;
+
+ shell_cf = XtCreatePopupShell("quit", transientShellWidgetClass,
+ toplevel, NULL, 0);
+ dialog = XtVaCreateManagedWidget("ask", dialogWidgetClass, shell_cf,
+ XtNvalue, XF86Config_path, NULL, 0);
+ XawDialogAddButton(dialog, "yes", WriteConfig, (XtPointer)1);
+ XawDialogAddButton(dialog, "no", WriteConfig, (XtPointer)0);
+ XawDialogAddButton(dialog, "cancel", WriteConfig, (XtPointer)-1);
+ XtRealizeWidget(shell_cf);
+ XSetWMProtocols(DPY, XtWindow(shell_cf), &wm_delete_window, 1);
+ XtSetArg(args[0], XtNlabel, &l);
+ XtGetValues(dialog, args, 1);
+ label = XtMalloc(len = (strlen(l) + strlen(XF86CONFIG) + 2));
+ XmuSnprintf(label, len, "%s\n", XF86CONFIG);
+ strcat(label, l);
+ XtSetArg(args[0], XtNlabel, label);
+ XtSetValues(dialog, args, 1);
+ XtFree(label);
+ }
+ else {
+ Arg args[2];
+ Cardinal num_args = 0;
+ char *l, *label = NULL, *str = "";
+
+ XtSetArg(args[0], XtNlabel, &l);
+ XtGetValues(dialog, args, 1);
+ switch (cf_state) {
+ case CF_XF86Config:
+ str = XF86CONFIG;
+ XtSetArg(args[num_args], XtNvalue, XF86Config_path);
+ ++num_args;
+ break;
+ case CF_XKBConfig:
+ str = "XKB";
+ XtSetArg(args[num_args], XtNvalue, XkbConfig_path);
+ ++num_args;
+ break;
+ }
+ l = strchr(l, '\n');
+ if (l != NULL) {
+ label = XtMalloc(strlen(str) + strlen(l) + 1);
+ strcpy(label, str);
+ strcat(label, l);
+ XtSetArg(args[num_args], XtNlabel, label);
+ ++num_args;
+ }
+ XtSetValues(dialog, args, num_args);
+ if (l != NULL)
+ XtFree(label);
+ }
+
+ asking_cf = 1;
+
+ XtPopup(shell_cf, XtGrabExclusive);
+ while (asking_cf)
+ XtAppProcessEvent(XtWidgetToApplicationContext(shell_cf), XtIMAll);
+
+ if (write_cf > 0) {
+ switch (cf_state) {
+ case CF_XF86Config:
+ XF86Config_path = XawDialogGetValueString(dialog);
+ XmuSnprintf(XF86Config_path_static,
+ sizeof(XF86Config_path_static),
+ "%s", XF86Config_path);
+ XF86Config_path = XF86Config_path_static;
+ break;
+ case CF_XKBConfig:
+ XkbConfig_path = XawDialogGetValueString(dialog);
+ XmuSnprintf(XkbConfig_path_static,
+ sizeof(XkbConfig_path_static),
+ "%s", XkbConfig_path);
+ XkbConfig_path = XkbConfig_path_static;
+ break;
+ }
+ }
+
+ return (write_cf);
+}
+
+/*ARGSUSED*/
+void
+PopdownErrorCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XtPopdown((Widget)user_data);
+}
+
+/*ARGSUSED*/
+void
+ErrorCancelAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+ XtPopdown((Widget)w);
+}
+
+/*ARGSUSED*/
+void
+QuitAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+ QuitCallback(w, NULL, NULL);
+}
+
+/*ARGSUSED*/
+void
+QuitCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ for (cf_state = CF_First; cf_state <= CF_Last; cf_state++) {
+ if (cf_state == CF_XKBConfig && xkb_info == NULL)
+ continue;
+
+ switch (AskConfig()) {
+ case 0:
+ break;
+ case 1:
+ if ((cf_state == CF_XF86Config &&
+ !xf86writeConfigFile(XF86Config_path, XF86Config)) ||
+ (cf_state == CF_XKBConfig &&
+ !WriteXKBConfiguration(XkbConfig_path,
+ &xkb_info->config))) {
+ static Widget shell;
+
+ if (shell == NULL) {
+ Widget dialog;
+
+ shell = XtCreatePopupShell("error",
+ transientShellWidgetClass,
+ toplevel, NULL, 0);
+ dialog = XtVaCreateManagedWidget("notice",
+ dialogWidgetClass,
+ shell, XtNvalue, NULL,
+ NULL, 0);
+ XawDialogAddButton(dialog, "ok", PopdownErrorCallback,
+ (XtPointer)shell);
+ XtRealizeWidget(shell);
+ XSetWMProtocols(DPY, XtWindow(shell),
+ &wm_delete_window, 1);
+ }
+ XtPopup(shell, XtGrabExclusive);
+ return;
+ }
+ break;
+ default:
+ return;
+ }
+ }
+
+ endx();
+ exit(0);
+}
+
+void
+InitializeDevices(void)
+{
+ xf86cfgDevice *device;
+ int mouse_x, mouse_y, keyboard_x, keyboard_y,
+ card_x, card_y, monitor_x, monitor_y, len;
+ XF86ConfInputPtr input = XF86Config->conf_input_lst;
+ XF86ConfDevicePtr card = XF86Config->conf_device_lst;
+ XF86ConfMonitorPtr monitor = XF86Config->conf_monitor_lst;
+ XF86OptionPtr flags = NULL;
+ char buffer[4096], *tip;
+ Arg args[1];
+
+ if (XF86Config->conf_flags != NULL)
+ flags = XF86Config->conf_flags->flg_option_lst;
+
+ len = 0;
+ while (flags && len < sizeof(buffer) - 1) {
+ len += XmuSnprintf(buffer + len, sizeof(buffer) - len,
+ "Option \"%s\"",
+ flags->opt_name);
+ if (flags->opt_val != NULL)
+ len += XmuSnprintf(buffer + len, sizeof(buffer) - len,
+ " \"%s\"\n",
+ flags->opt_val);
+ else
+ len += XmuSnprintf(buffer + len, sizeof(buffer) - len,
+ "%s", "\n");
+ flags = (XF86OptionPtr)(flags->list.next);
+ }
+
+ if (len) {
+ tip = XtNewString(buffer);
+ XtSetArg(args[0], XtNtip, tip);
+ XtSetValues(computer.cpu, args, 1);
+ }
+
+#define DEFAULT_MOUSE_WIDTH 30
+#define DEFAULT_MOUSE_HEIGHT 40
+#define DEFAULT_KEYBOARD_WIDTH 48
+#define DEFAULT_KEYBOARD_HEIGHT 36
+ mouse_x = work->core.width - (work->core.width >> 2);
+ mouse_y = work->core.height - DEFAULT_MOUSE_HEIGHT;
+ keyboard_x = 6;
+ keyboard_y = work->core.height - DEFAULT_KEYBOARD_HEIGHT;
+
+ while (input != NULL) {
+ if (input->inp_driver) {
+ if (strcasecmp(input->inp_driver, "mouse") == 0) {
+ device = AddDevice(MOUSE, (XtPointer)input, mouse_x, mouse_y);
+ SetTip(device);
+ if ((mouse_x += DEFAULT_MOUSE_WIDTH) > work->core.width) {
+ if ((mouse_y -= DEFAULT_MOUSE_HEIGHT) < (work->core.height >> 1))
+ mouse_y = work->core.height >> 1;
+ mouse_x = work->core.width - (work->core.width >> 2);
+ }
+ }
+ else if (strcasecmp(input->inp_driver, "keyboard") == 0) {
+ device = AddDevice(KEYBOARD, (XtPointer)input, keyboard_x, keyboard_y);
+ SetTip(device);
+ if ((keyboard_x += DEFAULT_KEYBOARD_WIDTH) >
+ work->core.width - (work->core.width >> 2)) {
+ if ((keyboard_y -= DEFAULT_KEYBOARD_HEIGHT) < (work->core.height >> 1))
+ keyboard_y = work->core.height >> 1;
+ keyboard_x = 6;
+ }
+ }
+ }
+ input = (XF86ConfInputPtr)(input->list.next);
+ }
+
+#define DEFAULT_CARD_WIDTH 45
+#define DEFAULT_CARD_HEIGHT 46
+ card_x = 6;
+ card_y = (work->core.height >> 1) - 20 - DEFAULT_CARD_HEIGHT;
+ while (card != NULL) {
+ device = AddDevice(CARD, (XtPointer)card, card_x, card_y);
+ SetTip(device);
+ if ((card_x += DEFAULT_CARD_WIDTH) > work->core.width) {
+ if ((card_y -= DEFAULT_CARD_HEIGHT) < (work->core.height >> 2))
+ card_y = work->core.height >> 2;
+ card_x = 6;
+ }
+ card = (XF86ConfDevicePtr)(card->list.next);
+ }
+
+#define DEFAULT_MONITOR_WIDTH 48
+#define DEFAULT_MONITOR_HEIGHT 48
+ monitor_x = 6;
+ monitor_y = 6;
+ while (monitor != NULL) {
+ XF86ConfScreenPtr screen = XF86Config->conf_screen_lst;
+
+ device = AddDevice(MONITOR, (XtPointer)monitor, monitor_x, monitor_y);
+ SetTip(device);
+ if ((monitor_x += DEFAULT_MONITOR_WIDTH) > work->core.width) {
+ if ((monitor_y += DEFAULT_MONITOR_HEIGHT) >
+ (work->core.height >> 2) - DEFAULT_MONITOR_HEIGHT)
+ monitor_y = (work->core.height >> 2) - DEFAULT_MONITOR_HEIGHT;
+ monitor_x = 6;
+ }
+
+ while (screen != NULL) {
+ if (screen->scrn_monitor == monitor) {
+ card = XF86Config->conf_device_lst;
+ while (card != NULL) {
+ if (screen->scrn_device == card) {
+ xf86cfgScreen *scr = (xf86cfgScreen*)
+ XtCalloc(1, sizeof(xf86cfgScreen));
+ int i;
+
+ for (i = 0; i < computer.num_devices; i++)
+ if ((XF86ConfDevicePtr)(computer.devices[i]->config)
+ == card)
+ break;
+ scr->screen = screen;
+ scr->card = computer.devices[i];
+ scr->monitor = device;
+ scr->refcount = 0;
+ ++scr->card->refcount;
+ ++scr->monitor->refcount;
+ computer.screens = (xf86cfgScreen**)
+ XtRealloc((XtPointer)computer.screens,
+ sizeof(xf86cfgScreen*) *
+ (computer.num_screens + 1));
+ CreateScreenWidget(scr);
+ scr->type = SCREEN;
+ computer.screens[computer.num_screens++] = scr;
+ SetTip((xf86cfgDevice*)scr);
+ break;
+ }
+ card = (XF86ConfDevicePtr)(card->list.next);
+ }
+ device->state = USED;
+ }
+ screen = (XF86ConfScreenPtr)(screen->list.next);
+ }
+
+ monitor = (XF86ConfMonitorPtr)(monitor->list.next);
+ }
+}
+
+xf86cfgDevice *
+AddDevice(int type, XtPointer config, int x, int y)
+{
+ switch (type) {
+ case MOUSE:
+ case KEYBOARD:
+ case CARD:
+ case MONITOR:
+ computer.devices = (xf86cfgDevice**)
+ XtRealloc((XtPointer)computer.devices,
+ sizeof(xf86cfgDevice*) * (computer.num_devices + 1));
+ computer.devices[computer.num_devices] = (xf86cfgDevice*)
+ XtCalloc(1, sizeof(xf86cfgDevice));
+ computer.devices[computer.num_devices]->config = config;
+ computer.devices[computer.num_devices]->widget =
+ XtVaCreateManagedWidget(device_names[type], simpleWidgetClass,
+ work,
+ XtNx, x,
+ XtNy, y,
+ XtNtip, NULL,
+ NULL, 0);
+ computer.devices[computer.num_devices]->type = type;
+ computer.devices[computer.num_devices]->state = UNUSED;
+ computer.devices[computer.num_devices]->refcount = 0;
+ ++computer.num_devices;
+ break;
+ default:
+ fprintf(stderr, "Bad argument to AddDevice.\n");
+ exit(1);
+ return (NULL);
+ }
+
+ UpdateMenuDeviceList(type);
+
+ return (computer.devices[computer.num_devices - 1]);
+}
+
+/*ARGSUSED*/
+static void
+HelpCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ char *topic = NULL;
+
+ switch (config_mode) {
+ case CONFIG_LAYOUT:
+ topic = HELP_DEVICES;
+ break;
+ case CONFIG_SCREEN:
+ topic = HELP_SCREEN;
+ break;
+ case CONFIG_MODELINE:
+ topic = HELP_MODELINE;
+ break;
+ case CONFIG_ACCESSX:
+ topic = HELP_ACCESSX;
+ break;
+ }
+ Help(topic);
+}
+
+void
+SelectLayoutCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ int i, j;
+ XF86ConfLayoutPtr lay = (XF86ConfLayoutPtr)user_data;
+ XF86ConfInputrefPtr input;
+ XF86ConfAdjacencyPtr adj;
+ Widget sme, layopt;
+ Arg args[1];
+ char *str;
+
+ /* XXX Needs to check computer.layout,
+ * because this function should also create
+ * a new layout...
+ */
+ if (lay == computer.layout && computer.layout)
+ return;
+
+ if (computer.layout != NULL) {
+ for (i = 0; i < computer.num_layouts; i++) {
+ if (computer.layouts[i]->layout == computer.layout)
+ break;
+ }
+ if (i < computer.num_layouts) {
+ XtFree((XtPointer)computer.layouts[i]->screen);
+ XtFree((XtPointer)computer.layouts[i]->position);
+ }
+ else {
+ computer.layouts = (xf86cfgLayout**)
+ XtRealloc((XtPointer)computer.layouts, sizeof(xf86cfgLayout*) *
+ (computer.num_layouts + 1));
+ ++computer.num_layouts;
+ }
+ computer.layouts[i] = (xf86cfgLayout*)XtCalloc(1, sizeof(xf86cfgLayout));
+ computer.layouts[i]->layout = computer.layout;
+ computer.layouts[i]->num_layouts = computer.num_screens;
+ computer.layouts[i]->screen = (xf86cfgScreen**)
+ XtMalloc(sizeof(xf86cfgScreen*) * computer.num_screens);
+ computer.layouts[i]->position = (XPoint*)
+ XtMalloc(sizeof(XPoint) * computer.num_screens);
+ for (j = 0; j < computer.num_screens; j++) {
+ computer.layouts[i]->screen[j] = computer.screens[j];
+ computer.layouts[i]->position[j].x = computer.screens[j]->widget->core.x;
+ computer.layouts[i]->position[j].y = computer.screens[j]->widget->core.y;
+ }
+ }
+
+ if (lay != NULL) {
+ for (i = 0; i < computer.num_layouts; i++)
+ if (computer.layouts[i]->layout == lay) {
+ for (j = 0; j < computer.layouts[i]->num_layouts; j++) {
+ int k;
+
+ for (k = 0; k < computer.num_screens; k++)
+ if (computer.screens[k] == computer.layouts[i]->screen[j]) {
+ XtMoveWidget(computer.screens[k]->widget,
+ computer.layouts[i]->position[j].x,
+ computer.layouts[i]->position[j].y);
+ }
+ }
+ break;
+ }
+
+ layoutsme = w;
+ XtSetArg(args[0], XtNlabel, &str);
+ XtGetValues(w, args, 1);
+ XtSetArg(args[0], XtNstring, str);
+ XtSetValues(layout, args, 1);
+ }
+
+ computer.layout = lay;
+
+ for (i = 0; i < computer.num_devices; i++)
+ computer.devices[i]->state = UNUSED;
+ for (i = 0; i < computer.num_screens; i++)
+ computer.screens[i]->state = UNUSED;
+
+ if (lay == NULL) {
+ char name[64];
+ XF86ConfLayoutPtr l;
+ int num_layouts = 0;
+
+ l = XF86Config->conf_layout_lst;
+ while (l != NULL) {
+ if (l->lay_adjacency_lst == NULL &&
+ l->lay_inactive_lst == NULL &&
+ l->lay_input_lst == NULL &&
+ l->lay_option_lst == NULL &&
+ l->lay_comment == NULL) {
+ for (i = 0;
+ i < ((CompositeWidget)layout)->composite.num_children; i++)
+ if (strcmp(XtName(((CompositeWidget)layout)->composite.
+ children[i]), l->lay_identifier) == 0) {
+ layoutsme = ((CompositeWidget)layout)->composite.children[i];
+ }
+ computer.layout = l;
+ XtSetArg(args[0], XtNstring, l->lay_identifier);
+ XtSetValues(layout, args, 1);
+ if (config_mode == CONFIG_LAYOUT)
+ DrawCables();
+ if (config_mode == CONFIG_SCREEN)
+ ScreenSetup(True);
+ return;
+ }
+ ++num_layouts;
+ l = (XF86ConfLayoutPtr)(l->list.next);
+ }
+ do {
+ XmuSnprintf(name, sizeof(name), "Layout%d", num_layouts);
+ ++num_layouts;
+ } while (xf86findLayout(name,
+ XF86Config->conf_layout_lst) != NULL);
+ l = (XF86ConfLayoutPtr)XtCalloc(1, sizeof(XF86ConfLayoutRec));
+
+ l->lay_identifier = XtNewString(name);
+ XF86Config->conf_layout_lst =
+ xf86addLayout(XF86Config->conf_layout_lst, l);
+ layoutsme = XtVaCreateManagedWidget("sme", smeBSBObjectClass,
+ layoutp,
+ XtNlabel, name,
+ XtNmenuName, l->lay_identifier,
+ XtNleftBitmap, menuPixmap,
+ NULL, 0);
+ XtAddCallback(layoutsme, XtNcallback,
+ SelectLayoutCallback, (XtPointer)l);
+
+ layopt = XtCreatePopupShell(l->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);
+
+ computer.layout = l;
+ XtSetArg(args[0], XtNstring, name);
+ XtSetValues(layout, args, 1);
+ if (config_mode == CONFIG_LAYOUT)
+ DrawCables();
+ if (config_mode == CONFIG_SCREEN)
+ ScreenSetup(True);
+ return;
+ }
+
+ input = lay->lay_input_lst;
+ adj = lay->lay_adjacency_lst;
+
+ for (i = 0; i < computer.num_devices; i++)
+ if (computer.devices[i]->config != NULL &&
+ (computer.devices[i]->type == MOUSE ||
+ computer.devices[i]->type == KEYBOARD)) {
+ while (input != NULL) {
+ if (strcmp(input->iref_inputdev_str, ((XF86ConfInputPtr)
+ (computer.devices[i]->config))->inp_identifier) == 0) {
+ computer.devices[i]->state = USED;
+ break;
+ }
+ input = (XF86ConfInputrefPtr)(input->list.next);
+ }
+ input = lay->lay_input_lst;
+ }
+
+ for (i = 0; i < computer.num_devices; i++)
+ if (computer.devices[i]->type == CARD) {
+ while (adj != NULL) {
+ XF86ConfScreenPtr screen = adj->adj_screen;
+
+ if (computer.devices[i]->config != NULL &&
+ strcmp(screen->scrn_device_str, ((XF86ConfDevicePtr)
+ (computer.devices[i]->config))->dev_identifier) == 0) {
+ int j;
+
+ for (j = 0; j < computer.num_screens; j++)
+ if (computer.screens[j]->card == computer.devices[i])
+ break;
+ computer.screens[j]->card->state = USED;
+ if (computer.screens[j]->monitor != NULL)
+ computer.screens[j]->monitor->state = USED;
+ computer.screens[j]->state = USED;
+ }
+
+ adj = (XF86ConfAdjacencyPtr)(adj->list.next);
+ }
+ adj = lay->lay_adjacency_lst;
+ }
+
+ if (config_mode == CONFIG_LAYOUT)
+ DrawCables();
+ else if (config_mode == CONFIG_SCREEN)
+ ScreenSetup(True);
+}
+
+/*ARGSUSED*/
+void
+DefaultLayoutCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Widget layopt, sme;
+ int i;
+ char *str;
+ XF86ConfLayoutPtr prev, tmp, lay;
+
+ str = w && XtParent(w) ? XtName(XtParent(w)) : NULL;
+ if (str == NULL)
+ return;
+
+ prev = XF86Config->conf_layout_lst;
+ lay = xf86findLayout(str, prev);
+ if (prev == lay)
+ return;
+
+ tmp = prev;
+ while (tmp != NULL) {
+ if (tmp == lay)
+ break;
+ prev = tmp;
+ tmp = (XF86ConfLayoutPtr)(tmp->list.next);
+ }
+
+ 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]);
+
+ prev->list.next = lay->list.next;
+ lay->list.next = XF86Config->conf_layout_lst;
+ XF86Config->conf_layout_lst = lay;
+
+ layoutsme = NULL;
+ 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);
+ }
+ SelectLayoutCallback(layoutsme,
+ XF86Config->conf_layout_lst, NULL);
+}
+
+/*ARGSUSED*/
+void
+RemoveLayoutCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XF86ConfLayoutPtr prev, tmp, lay, rem;
+ Widget sme = NULL;
+ int i;
+ char *str;
+ Arg args[1];
+
+ str = w && XtParent(w) ? XtName(XtParent(w)) : NULL;
+ if (str == NULL)
+ return;
+
+ prev = XF86Config->conf_layout_lst;
+ lay = xf86findLayout(str, prev);
+ tmp = prev;
+ while (tmp != NULL) {
+ if (tmp == lay)
+ break;
+ prev = tmp;
+ tmp = (XF86ConfLayoutPtr)(tmp->list.next);
+ }
+
+ rem = lay;
+ if (tmp != NULL)
+ lay = (XF86ConfLayoutPtr)(tmp->list.next);
+ if (lay == NULL && prev != tmp)
+ lay = prev;
+
+ if (lay != NULL) {
+ int i;
+
+ for (i = 0; i < ((CompositeWidget)layoutp)->composite.num_children;
+ i++) {
+ XtSetArg(args[0], XtNlabel, &str);
+ XtGetValues(((CompositeWidget)layoutp)->composite.children[i],
+ args, 1);
+ if (strcmp(lay->lay_identifier, str) == 0) {
+ layoutsme = ((CompositeWidget)layoutp)->composite.children[i];
+ break;
+ }
+ }
+ SelectLayoutCallback(layoutsme, lay, NULL);
+ }
+ else {
+ computer.layout = NULL;
+ XtSetArg(args[0], XtNstring, "");
+ XtSetValues(layout, args, 1);
+
+ for (i = 0; i < computer.num_devices; i++)
+ computer.devices[i]->state = UNUSED;
+ DrawCables();
+ }
+
+ for (i = 0; i < ((CompositeWidget)layoutp)->composite.num_children; i++) {
+ XtSetArg(args[0], XtNlabel, &str);
+ XtGetValues(((CompositeWidget)layoutp)->composite.children[i], args, 1);
+ if (strcmp(rem->lay_identifier, str) == 0) {
+ sme = ((CompositeWidget)layoutp)->composite.children[i];
+ break;
+ }
+ }
+
+ xf86removeLayout(XF86Config, rem);
+ if (sme)
+ XtDestroyWidget(sme);
+}
+
+void
+SetTip(xf86cfgDevice *device)
+{
+ XF86OptionPtr option = NULL;
+ char *tip, buffer[4096];
+ Arg args[1];
+ int len = 0;
+
+ XtSetArg(args[0], XtNtip, &tip);
+ XtGetValues(device->widget, args, 1);
+
+ switch (device->type) {
+ case MOUSE: {
+ XF86ConfInputPtr mouse = (XF86ConfInputPtr)device->config;
+
+ if (mouse == NULL)
+ return;
+ len = XmuSnprintf(buffer, sizeof(buffer),
+ "Identifier \"%s\"\n"
+ "Driver \"mouse\"\n",
+ mouse->inp_identifier);
+ option = mouse->inp_option_lst;
+ } break;
+ case KEYBOARD: {
+ XF86ConfInputPtr keyboard = (XF86ConfInputPtr)device->config;
+
+ if (keyboard == NULL)
+ return;
+ len = XmuSnprintf(buffer, sizeof(buffer),
+ "Identifier \"%s\"\n"
+ "Driver \"keyboard\"\n",
+ keyboard->inp_identifier);
+ option = keyboard->inp_option_lst;
+ } break;
+ case CARD: {
+ XF86ConfDevicePtr card = (XF86ConfDevicePtr)device->config;
+
+ if (card == NULL)
+ return;
+ len = XmuSnprintf(buffer, sizeof(buffer),
+ "Identifier \"%s\"\n"
+ "Driver \"%s\"\n",
+ card->dev_identifier,
+ card->dev_driver);
+ option = card->dev_option_lst;
+ } break;
+ case MONITOR: {
+ XF86ConfMonitorPtr monitor = (XF86ConfMonitorPtr)device->config;
+
+ if (monitor == NULL)
+ return;
+ len = XmuSnprintf(buffer, sizeof(buffer),
+ "Identifier \"%s\"\n"
+ "Vendor \"%s\"\n",
+ monitor->mon_identifier,
+ monitor->mon_vendor);
+ option = monitor->mon_option_lst;
+ } break;
+ case SCREEN: {
+ XF86ConfScreenPtr screen = (XF86ConfScreenPtr)device->config;
+
+ if (screen == NULL)
+ return;
+ len = XmuSnprintf(buffer, sizeof(buffer),
+ "Identifier \"%s\"\n",
+ screen->scrn_identifier);
+ if (screen->scrn_device_str != NULL)
+ len += XmuSnprintf(buffer + len, sizeof(buffer),
+ "Device \"%s\"\n",
+ screen->scrn_device_str);
+ if (screen->scrn_monitor_str != NULL)
+ len += XmuSnprintf(buffer + len, sizeof(buffer),
+ "Monitor \"%s\"\n",
+ screen->scrn_monitor_str);
+ option = screen->scrn_option_lst;
+ } break;
+ case SERVER: {
+ len = XmuSnprintf(buffer, sizeof(buffer),
+ "%s\n", "Server Flags");
+ option = XF86Config->conf_flags->flg_option_lst;
+ } break;
+ }
+
+ while (option && len < sizeof(buffer) - 1) {
+ len += XmuSnprintf(buffer + len, sizeof(buffer) - len,
+ "Option \"%s\"",
+ option->opt_name);
+ if (option->opt_val != NULL)
+ len += XmuSnprintf(buffer + len, sizeof(buffer) - len,
+ " \"%s\"\n",
+ option->opt_val);
+ else
+ len += XmuSnprintf(buffer + len, sizeof(buffer) - len,
+ "%s", "\n");
+ option = (XF86OptionPtr)(option->list.next);
+ }
+
+ tip = buffer;
+ XtSetArg(args[0], XtNtip, tip);
+ XtSetValues(device->widget, args, 1);
+}
+
+/*ARGSUSED*/
+void
+AddDeviceCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ AddDevice((long)user_data, NULL, 6, 6);
+}
+
+void
+SmeConfigureDeviceCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ int i;
+
+ switch ((long)user_data) {
+ case MOUSE:
+ case KEYBOARD:
+ case CARD:
+ case MONITOR:
+ for (i = 0; i < computer.num_devices; i++)
+ if (computer.devices[i]->type == (long)user_data) {
+ config = computer.devices[i]->widget;
+ ConfigureDeviceCallback(w, NULL, NULL);
+ }
+ break;
+
+ /* hack for newly added devices */
+ case -(MOUSE + 100):
+ case -(KEYBOARD + 100):
+ case -(CARD + 100):
+ case -(MONITOR + 100):
+ for (i = 0; i < computer.num_devices; i++)
+ if (-(computer.devices[i]->type + 100) == (long)user_data &&
+ computer.devices[i]->config == NULL) {
+ config = computer.devices[i]->widget;
+ ConfigureDeviceCallback(w, NULL, NULL);
+ }
+ break;
+
+ default:
+ for (i = 0; i < computer.num_devices; i++)
+ if (computer.devices[i]->config == user_data) {
+ config = computer.devices[i]->widget;
+ ConfigureDeviceCallback(w, NULL, NULL);
+ }
+ break;
+ }
+}
+
+void
+ConfigureDeviceCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ int i, j;
+
+ if (config_mode == CONFIG_LAYOUT) {
+ for (i = 0; i < computer.num_devices; i++) {
+ if (computer.devices[i]->widget == config) {
+ switch (computer.devices[i]->type) {
+ case MOUSE: {
+ XF86ConfInputPtr mouse =
+ MouseConfig(computer.devices[i]->config);
+
+ if (mouse != NULL && computer.devices[i]->config == NULL) {
+ XF86Config->conf_input_lst =
+ xf86addInput(XF86Config->conf_input_lst,
+ mouse);
+ computer.devices[i]->config = (XtPointer)mouse;
+ }
+ SetTip(computer.devices[i]);
+ } break;
+ case KEYBOARD: {
+ XF86ConfInputPtr keyboard =
+ KeyboardConfig(computer.devices[i]->config);
+
+ if (keyboard != NULL && computer.devices[i]->config == NULL) {
+ XF86Config->conf_input_lst =
+ xf86addInput(XF86Config->conf_input_lst,
+ keyboard);
+ computer.devices[i]->config = (XtPointer)keyboard;
+ }
+ SetTip(computer.devices[i]);
+ } break;
+ case CARD: {
+ XF86ConfDevicePtr card =
+ CardConfig(computer.devices[i]->config);
+
+ if (card != NULL && computer.devices[i]->config == NULL) {
+ XF86Config->conf_device_lst =
+ xf86addDevice(XF86Config->conf_device_lst,
+ card);
+ computer.devices[i]->config = (XtPointer)card;
+ }
+ SetTip(computer.devices[i]);
+ for (j = 0; j < computer.num_screens; j++)
+ if (computer.screens[j]->card->widget == config)
+ SetTip((xf86cfgDevice*)computer.screens[j]);
+ } break;
+ case MONITOR: {
+ XF86ConfMonitorPtr monitor =
+ MonitorConfig(computer.devices[i]->config);
+
+ if (monitor != NULL && computer.devices[i]->config == NULL) {
+ XF86Config->conf_monitor_lst =
+ xf86addMonitor(XF86Config->conf_monitor_lst,
+ monitor);
+ computer.devices[i]->config = (XtPointer)monitor;
+ }
+ SetTip(computer.devices[i]);
+ for (j = 0; j < computer.num_screens; j++)
+ if (computer.screens[j]->monitor->widget == config)
+ SetTip((xf86cfgDevice*)computer.screens[j]);
+ } break;
+ }
+ /* Need to update because it may have been renamed */
+ UpdateMenuDeviceList(computer.devices[i]->type);
+ break;
+ }
+ }
+ }
+ else if (config_mode == CONFIG_SCREEN) {
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->widget == config) {
+ if (ScreenConfig(computer.screens[i]->screen) != NULL)
+ SetTip((xf86cfgDevice*)computer.screens[i]);
+ }
+ }
+}
+
+void
+OptionsCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ int i;
+ XF86OptionPtr *options = NULL;
+#ifdef USE_MODULES
+ xf86cfgModuleOptions *drv_opts = NULL;
+#endif
+
+ if (config_mode == CONFIG_SCREEN) {
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->widget == config) {
+ options = &(computer.screens[i]->screen->scrn_option_lst);
+ break;
+ }
+ }
+ else {
+ for (i = 0; i < computer.num_devices; i++)
+ if (computer.devices[i]->widget == config)
+ break;
+
+ if (i >= computer.num_devices) {
+ if (XF86Config->conf_flags == NULL)
+ XF86Config->conf_flags = (XF86ConfFlagsPtr)
+ XtCalloc(1, sizeof(XF86ConfFlagsRec));
+ options = &(XF86Config->conf_flags->flg_option_lst);
+ }
+ else {
+ switch (computer.devices[i]->type) {
+ case MOUSE:
+ case KEYBOARD:
+ options = (XF86OptionPtr*)&(((XF86ConfInputPtr)
+ (computer.devices[i]->config))->inp_option_lst);
+#ifdef USE_MODULES
+ if (!nomodules) {
+ char *drv = ((XF86ConfInputPtr)
+ (computer.devices[i]->config))->inp_driver;
+
+ if (drv) {
+ drv_opts = module_options;
+ while (drv_opts) {
+ if (drv_opts->type == InputModule &&
+ strcmp(drv_opts->name, drv) == 0)
+ break;
+ drv_opts = drv_opts->next;
+ }
+ }
+ }
+#endif
+
+ break;
+ case CARD:
+ options = (XF86OptionPtr*)&(((XF86ConfDevicePtr)
+ (computer.devices[i]->config))->dev_option_lst);
+#ifdef USE_MODULES
+ if (!nomodules) {
+ char *drv = ((XF86ConfDevicePtr)
+ (computer.devices[i]->config))->dev_driver;
+
+ if (drv) {
+ drv_opts = module_options;
+ while (drv_opts) {
+ if (drv_opts->type == VideoModule &&
+ strcmp(drv_opts->name, drv) == 0)
+ break;
+ drv_opts = drv_opts->next;
+ }
+ }
+ }
+#endif
+ break;
+ case MONITOR:
+ options = (XF86OptionPtr*)&(((XF86ConfMonitorPtr)
+ (computer.devices[i]->config))->mon_option_lst);
+ break;
+ }
+ }
+ }
+
+#ifdef USE_MODULES
+ OptionsPopup(options, drv_opts ? drv_opts->name : NULL,
+ drv_opts ? drv_opts->option : NULL);
+#else
+ OptionsPopup(options);
+#endif
+ if (config_mode == CONFIG_SCREEN) {
+ XF86OptionPtr option, options;
+ int rotate = 0;
+
+ options = computer.screens[i]->screen->scrn_option_lst;
+ if ((option = xf86findOption(options, "Rotate")) != NULL) {
+ if (option->opt_val != NULL)
+ rotate = strcasecmp(option->opt_val, "CW") == 0 ? 1 :
+ strcasecmp(option->opt_val, "CCW") == 0 ? -1 : 0;
+ XtFree(option->opt_val);
+ option->opt_val = XtNewString(rotate > 0 ? "CW" : "CCW");
+ computer.screens[i]->rotate = rotate;
+ }
+ else
+ computer.screens[i]->rotate = 0;
+ UpdateScreenUI();
+ AdjustScreenUI();
+ SetTip((xf86cfgDevice*)computer.screens[i]);
+ }
+ else {
+ if (i >= computer.num_devices)
+ SetTip(&cpu_device);
+ else
+ SetTip(computer.devices[i]);
+ }
+}
+
+void
+EnableDeviceCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ int i;
+
+ if (config_mode == CONFIG_SCREEN) {
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->widget == config) {
+ computer.screens[i]->state = USED;
+ computer.screens[i]->card->state = USED;
+ ScreenSetup(False);
+ return;
+ }
+ }
+
+ for (i = 0; i < computer.num_devices; i++)
+ if (computer.devices[i]->widget == config) {
+ if (computer.devices[i]->state == USED)
+ return;
+ computer.devices[i]->state = USED;
+ DrawCables();
+ break;
+ }
+ if (i >= computer.num_devices || computer.layout == NULL)
+ return;
+ switch (computer.devices[i]->type) {
+ case MOUSE:
+ case KEYBOARD: {
+ int nmouses = 0, nkeyboards = 0;
+ XF86ConfInputPtr input = (XF86ConfInputPtr)
+ (computer.devices[i]->config);
+ XF86ConfInputrefPtr nex, iref = computer.layout->lay_input_lst;
+ XF86OptionPtr option;
+
+ nex = iref;
+ while (nex != NULL) {
+ if (strcasecmp(nex->iref_inputdev->inp_driver, "mouse") == 0)
+ ++nmouses;
+ else if (strcasecmp(nex->iref_inputdev->inp_driver,
+ "keyboard") == 0)
+ ++nkeyboards;
+ iref = nex;
+ nex = (XF86ConfInputrefPtr)(nex->list.next);
+ }
+ nex = (XF86ConfInputrefPtr)XtCalloc(1, sizeof(XF86ConfInputrefRec));
+ nex->list.next = NULL;
+ nex->iref_inputdev = input;
+ nex->iref_inputdev_str = XtNewString(input->inp_identifier);
+ if (nmouses == 0 && computer.devices[i]->type == MOUSE)
+ option = xf86newOption(XtNewString("CorePointer"), NULL);
+ else if (nkeyboards == 0 && computer.devices[i]->type == KEYBOARD)
+ option = xf86newOption(XtNewString("CoreKeyboard"), NULL);
+ else
+ option = xf86newOption(XtNewString("SendCoreEvents"), NULL);
+ nex->iref_option_lst = option;
+ computer.layout->lay_input_lst =
+ xf86addInputref(computer.layout->lay_input_lst, nex);
+ } break;
+ case CARD:
+ for (i = 0; i < computer.num_screens; i++) {
+ if (computer.screens[i]->card->widget == config &&
+ computer.screens[i]->state != USED) {
+ XF86ConfAdjacencyPtr adj;
+
+ adj = (XF86ConfAdjacencyPtr)
+ XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
+ adj->adj_screen = computer.screens[i]->screen;
+ adj->adj_screen_str = XtNewString(computer.screens[i]->
+ screen->scrn_identifier);
+ computer.layout->lay_adjacency_lst = (XF86ConfAdjacencyPtr)
+ xf86addListItem((GenericListPtr)computer.layout->
+ lay_adjacency_lst, (GenericListPtr)adj);
+ computer.screens[i]->state = USED;
+ }
+ }
+ break;
+ case MONITOR:
+ break;
+ }
+}
+
+void
+DisableDeviceCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ int i;
+
+ if (config_mode == CONFIG_SCREEN) {
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->widget == config) {
+ computer.screens[i]->state = UNUSED;
+ computer.screens[i]->card->state = UNUSED;
+ ScreenSetup(False);
+ return;
+ }
+ }
+
+ for (i = 0; i < computer.num_devices; i++)
+ if (computer.devices[i]->widget == config) {
+ if (computer.devices[i]->state == UNUSED)
+ return;
+ computer.devices[i]->state = UNUSED;
+ DrawCables();
+ break;
+ }
+ if (i >= computer.num_devices || computer.layout == NULL)
+ return;
+ switch (computer.devices[i]->type) {
+ case MOUSE:
+ case KEYBOARD:
+ xf86removeInputRef(computer.layout,
+ (XF86ConfInputPtr)(computer.devices[i]->config));
+ break;
+ case CARD: {
+ XF86ConfAdjacencyPtr adj;
+ int j;
+
+ if (computer.layout == NULL)
+ break;
+ for (j = 0; j < computer.num_screens; j++)
+ if (computer.screens[j]->card->widget == config) {
+ adj = computer.layout->lay_adjacency_lst;
+ while (adj != NULL) {
+ if (adj->adj_screen == computer.screens[j]->screen) {
+ xf86removeAdjacency(computer.layout, adj);
+ break;
+ }
+ adj = (XF86ConfAdjacencyPtr)(adj->list.next);
+ }
+ computer.screens[j]->state = UNUSED;
+ break;
+ }
+ } break;
+ case MONITOR:
+ break;
+ }
+}
+
+/* ARGSUSED */
+void
+RemoveDeviceCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ int i, j;
+
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->widget == config) {
+ RemoveScreen(computer.screens[i]->monitor,
+ computer.screens[i]->card);
+ ScreenSetup(False);
+ return;
+ }
+
+ for (i = 0; i < computer.num_devices; i++) {
+ if (computer.devices[i]->widget == config) {
+ switch (computer.devices[i]->type) {
+ case MOUSE:
+ case KEYBOARD:
+ xf86removeInput(XF86Config,
+ (XF86ConfInputPtr)(computer.devices[i]->config));
+ break;
+ case CARD:
+ case MONITOR:
+ break;
+ }
+
+ if (computer.devices[i]->type == CARD) {
+ for (j = 0; j < computer.num_screens; j++)
+ if (computer.screens[j]->card == computer.devices[i]) {
+ RemoveScreen(computer.screens[j]->monitor,
+ computer.devices[i]);
+ --j;
+ }
+ if (computer.devices[i]->refcount <= 0)
+ xf86removeDevice(XF86Config,
+ (XF86ConfDevicePtr)(computer.devices[i]->config));
+ }
+ else if (computer.devices[i]->type == MONITOR) {
+ for (j = 0; j < computer.num_screens; j++)
+ if (computer.screens[j]->monitor == computer.devices[i]) {
+ RemoveScreen(computer.devices[i],
+ computer.screens[j]->card);
+ --j;
+ }
+ if (computer.devices[i]->refcount <= 0)
+ xf86removeMonitor(XF86Config,
+ (XF86ConfMonitorPtr)(computer.devices[i]->config));
+ }
+
+ if (computer.devices[i]->refcount <= 0) {
+ int type = computer.devices[i]->type;
+
+ XtDestroyWidget(computer.devices[i]->widget);
+ XtFree((XtPointer)computer.devices[i]);
+ if (--computer.num_devices > i)
+ memmove(&computer.devices[i], &computer.devices[i + 1],
+ (computer.num_devices - i) * sizeof(xf86cfgDevice*));
+
+ DrawCables();
+ UpdateMenuDeviceList(type);
+ }
+
+ break;
+ }
+ }
+}
+
+void
+UpdateMenuDeviceList(int type)
+{
+ Widget sme = NULL, menu = NULL;
+ int i, count;
+ static char *mouseM = "mouseM", *keyboardM = "keyboardM",
+ *cardM = "cardM", *monitorM = "monitorM";
+
+ for (i = count = 0; i < computer.num_devices; i++)
+ if (computer.devices[i]->type == type)
+ ++count;
+
+ switch (type) {
+ case MOUSE:
+ sme = mouseSme;
+ menu = mouseMenu;
+ break;
+ case KEYBOARD:
+ sme = keyboardSme;
+ menu = keyboardMenu;
+ break;
+ case CARD:
+ sme = cardSme;
+ menu = cardMenu;
+ break;
+ case MONITOR:
+ sme = monitorSme;
+ menu = monitorMenu;
+ break;
+ }
+
+ if (menu)
+ for (i = ((CompositeWidget)menu)->composite.num_children - 1; i >= 0; i--)
+ XtDestroyWidget(((CompositeWidget)menu)->composite.children[i]);
+
+ if (count < 2) {
+ XtVaSetValues(sme, XtNmenuName, NULL, XtNleftBitmap, None, NULL);
+ return;
+ }
+
+ switch (type) {
+ case MOUSE:
+ if (mouseMenu == NULL)
+ menu = mouseMenu =
+ XtCreatePopupShell(mouseM, simpleMenuWidgetClass,
+ XtParent(mouseSme), NULL, 0);
+ XtVaSetValues(mouseSme, XtNmenuName, mouseM,
+ XtNleftBitmap, menuPixmap, NULL);
+ break;
+ case KEYBOARD:
+ if (keyboardMenu == NULL)
+ menu = keyboardMenu =
+ XtCreatePopupShell(keyboardM, simpleMenuWidgetClass,
+ XtParent(keyboardSme), NULL, 0);
+ XtVaSetValues(keyboardSme, XtNmenuName, keyboardM,
+ XtNleftBitmap, menuPixmap, NULL);
+ break;
+ case CARD:
+ if (cardMenu == NULL)
+ menu = cardMenu =
+ XtCreatePopupShell(cardM, simpleMenuWidgetClass,
+ XtParent(cardSme), NULL, 0);
+ XtVaSetValues(cardSme, XtNmenuName, cardM,
+ XtNleftBitmap, menuPixmap, NULL);
+ break;
+ case MONITOR:
+ if (monitorMenu == NULL)
+ menu = monitorMenu =
+ XtCreatePopupShell(monitorM, simpleMenuWidgetClass,
+ XtParent(monitorSme), NULL, 0);
+ XtVaSetValues(monitorSme, XtNmenuName, monitorM,
+ XtNleftBitmap, menuPixmap, NULL);
+ break;
+ }
+
+ for (i = 0; i < computer.num_devices; i++)
+ if (computer.devices[i]->type == type) {
+ char *label = NULL;
+
+ if (computer.devices[i]->config) {
+ switch (type) {
+ case MOUSE:
+ case KEYBOARD:
+ label = ((XF86ConfInputPtr)computer.devices[i]->config)
+ ->inp_identifier;
+ break;
+ case CARD:
+ label = ((XF86ConfDevicePtr)computer.devices[i]->config)
+ ->dev_identifier;
+ break;
+ case MONITOR:
+ label = ((XF86ConfMonitorPtr)computer.devices[i]->config)
+ ->mon_identifier;
+ break;
+ }
+ }
+ else {
+ switch (type) {
+ case MOUSE:
+ label = "newMouse";
+ break;
+ case KEYBOARD:
+ label = "newKeyboard";
+ break;
+ case CARD:
+ label = "newCard";
+ break;
+ case MONITOR:
+ label = "newMonitor";
+ break;
+ }
+ }
+
+ sme = XtCreateManagedWidget(label, smeBSBObjectClass, menu, NULL, 0);
+ XtAddCallback(sme, XtNcallback, SmeConfigureDeviceCallback,
+ computer.devices[i]->config ?
+ computer.devices[i]->config :
+ (XtPointer) (-((long)type + 100)));
+ }
+}
+
+/*ARGSUSED*/
+void
+SelectDeviceAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+ device = w;
+ xpos = event->xbutton.x_root;
+ ypos = event->xbutton.y_root;
+ XDefineCursor(XtDisplay(device), XtWindow(device), no_cursor);
+
+ if (config_mode == CONFIG_SCREEN) {
+ sxpos = device->core.x;
+ sypos = device->core.y;
+ }
+}
+
+/*ARGSUSED*/
+void
+MoveDeviceAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+ int dx, dy, x, y, oldx, oldy;
+
+ if (device == NULL || device != w)
+ return;
+
+ dx = event->xbutton.x_root - xpos;
+ dy = event->xbutton.y_root - ypos;
+
+ oldx = device->core.x;
+ oldy = device->core.y;
+ x = device->core.x + dx;
+ y = device->core.y + dy;
+
+ if (x < 0)
+ x = 0;
+ else if (x + device->core.width > XtParent(device)->core.width)
+ x = XtParent(device)->core.width - device->core.width;
+ if (y < 0)
+ y = 0;
+ else if (y + device->core.height > XtParent(device)->core.height)
+ y = XtParent(device)->core.height - device->core.height;
+
+ dx = x - oldx;
+ dy = y - oldy;
+
+ XRaiseWindow(XtDisplay(device), XtWindow(device));
+ XtMoveWidget(device, x, y);
+
+ xpos += dx;
+ ypos += dy;
+}
+
+/*ARGSUSED*/
+void
+UnselectDeviceAction(Widget w, XEvent *ev, String *params, Cardinal *num_params)
+{
+ if (device != NULL) {
+ XUndefineCursor(XtDisplay(device), XtWindow(device));
+
+ if (config_mode == CONFIG_SCREEN)
+ ScreenSetup(False);
+ device = NULL;
+ }
+}
+
+/*ARGSUSED*/
+void
+DevicePopupMenu(Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+ static Widget configure, options, enable, disable, remove;
+ static int first = 1;
+ int i;
+ xf86cfgDevice *dev;
+
+ if (first) {
+ first = 0;
+
+ popup = XtCreatePopupShell("popup", simpleMenuWidgetClass,
+ toplevel, NULL, 0);
+ configure = XtCreateManagedWidget("configure", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(configure, XtNcallback, ConfigureDeviceCallback, NULL);
+ options = XtCreateManagedWidget("options", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(options, XtNcallback, OptionsCallback, NULL);
+ XtCreateManagedWidget("line", smeLineObjectClass,
+ popup, NULL, 0);
+ enable = XtCreateManagedWidget("enable", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(enable, XtNcallback, EnableDeviceCallback, NULL);
+ disable = XtCreateManagedWidget("disable", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(disable, XtNcallback, DisableDeviceCallback, NULL);
+ XtCreateManagedWidget("line", smeLineObjectClass,
+ popup, NULL, 0);
+ remove = XtCreateManagedWidget("remove", smeBSBObjectClass,
+ popup, NULL, 0);
+ XtAddCallback(remove, XtNcallback, RemoveDeviceCallback, NULL);
+
+ XtRealizeWidget(popup);
+ }
+
+ dev = NULL;
+ if (config_mode == CONFIG_LAYOUT) {
+ for (i = 0; i < computer.num_devices; i++)
+ if (computer.devices[i]->widget == w) {
+ dev = computer.devices[i];
+ break;
+ }
+ if (i >= computer.num_devices && strcmp(XtName(w), "cpu"))
+ return;
+ if (dev == NULL)
+ dev = &cpu_device;
+ }
+ else if (config_mode == CONFIG_SCREEN) {
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->widget == w) {
+ dev = (xf86cfgDevice*)computer.screens[i];
+ break;
+ }
+ }
+ if (dev == NULL)
+ return;
+
+ config = w;
+
+ if (dev->type != SERVER) {
+ XtSetSensitive(configure, True);
+ XtSetSensitive(remove, True);
+ XtSetSensitive(options, dev->config != NULL);
+ if (computer.layout == NULL || dev->config == NULL ||
+ dev->type == MONITOR) {
+ XtSetSensitive(enable, False);
+ XtSetSensitive(disable, False);
+ }
+ else if (dev->state == USED) {
+ XtSetSensitive(enable, False);
+ XtSetSensitive(disable, True);
+ }
+ else {
+ XtSetSensitive(enable, True);
+ XtSetSensitive(disable, False);
+ }
+ }
+ else {
+ XtSetSensitive(configure, False);
+ XtSetSensitive(options, True);
+ XtSetSensitive(enable, False);
+ XtSetSensitive(disable, False);
+ XtSetSensitive(remove, False);
+ }
+
+ XtMoveWidget(popup, event->xbutton.x_root, event->xbutton.y_root);
+ XtPopup(popup, XtGrabNone);
+}
+
+/*ARGSUSED*/
+void
+DevicePopdownMenu(Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+ if (popup && XtIsRealized(popup))
+ XtPopdown(popup);
+}
+
+void RenameLayoutAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ XF86ConfLayoutPtr lay = XF86Config->conf_layout_lst;
+ Arg args[1];
+ char *name;
+
+ XtSetArg(args[0], XtNstring, &name);
+ XtGetValues(layout, args, 1);
+
+ if (computer.layout == NULL || (computer.layout &&
+ strcasecmp(name, computer.layout->lay_identifier)) == 0)
+ return;
+
+ if (name == NULL && *name == '\0') {
+ /* tell user about error */
+ return;
+ }
+
+ while (lay) {
+ if (strcasecmp(name, lay->lay_identifier) == 0)
+ /* tell user about error */
+ return;
+ lay = (XF86ConfLayoutPtr)(lay->list.next);
+ }
+
+ XtSetArg(args[0], XtNlabel, name);
+ XtSetValues(layoutsme, args, 1);
+ xf86renameLayout(XF86Config, computer.layout, name);
+}
+
+/*ARGSUSED*/
+static void
+ComputerEventHandler(Widget w, XtPointer closure,
+ XEvent *event, Boolean *continue_to_dispatch)
+{
+ if (event->xexpose.count > 1)
+ return;
+
+ if (config_mode == CONFIG_LAYOUT)
+ DrawCables();
+}
+
+void
+DrawCables(void)
+{
+ Display *display;
+ Window window;
+ int ox, oy, i;
+ xf86cfgScreen **scr = computer.screens;
+
+ if (config_mode != CONFIG_LAYOUT)
+ return;
+
+ ox = computer.cpu->core.x + (computer.cpu->core.width >> 1);
+ oy = computer.cpu->core.y + (computer.cpu->core.height >> 1);
+
+ display = XtDisplay(work);
+ window = XtWindow(work);
+ XClearWindow(display, window);
+
+ for (i = 0; i < computer.num_devices; i++) {
+ if (computer.devices[i]->state == USED &&
+ computer.devices[i]->type != MONITOR)
+ DrawCable(display, window, ox, oy,
+ computer.devices[i]->widget->core.x +
+ (computer.devices[i]->widget->core.width>>1),
+ computer.devices[i]->widget->core.y +
+ (computer.devices[i]->widget->core.height>>1));
+
+ }
+ for (i = 0; i < computer.num_screens; i++) {
+ if (scr[i]->monitor != NULL)
+ DrawCable(display, window,
+ scr[i]->card->widget->core.x +
+ (scr[i]->card->widget->core.width>>1),
+ scr[i]->card->widget->core.y +
+ (scr[i]->card->widget->core.height>>1),
+ scr[i]->monitor->widget->core.x +
+ (scr[i]->monitor->widget->core.width>>1),
+ scr[i]->monitor->widget->core.y +
+ (scr[i]->monitor->widget->core.height>>1));
+ }
+}
+
+static void
+DrawCable(Display *display, Window window, int o_x, int o_y, int d_x, int d_y)
+{
+ XDrawLine(display, window, cablegcshadow, o_x, o_y, d_x, d_y);
+ XDrawLine(display, window, cablegc, o_x, o_y, d_x, d_y);
+}
+
+/*ARGSUSED*/
+void
+SetConfigModeCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ int i, mode = (long)user_data;
+ Arg args[3];
+ char *ptr;
+ static Dimension height;
+
+ if (mode == config_mode)
+ return;
+ XtSetArg(args[0], XtNlabel, &ptr);
+ XtGetValues(w, args, 1);
+ XtSetArg(args[0], XtNlabel, ptr);
+ XtSetValues(topMenu, args, 1);
+
+ if (config_mode == CONFIG_LAYOUT) {
+ XtSetArg(args[0], XtNheight, &height);
+ XtGetValues(commands, args, 1);
+ for (i = 0; i < computer.num_devices; i++)
+ XtUnmapWidget(computer.devices[i]->widget);
+ XtUnmapWidget(commands);
+ XtUnmapWidget(computer.cpu);
+ XtSetSensitive(commands, False);
+ XtSetArg(args[0], XtNheight, 1);
+ XtSetArg(args[1], XtNmin, 1);
+ XtSetArg(args[2], XtNmax, 1);
+ XtSetValues(commands, args, 3);
+ }
+ else if (config_mode == CONFIG_SCREEN) {
+ for (i = 0; i < computer.num_screens; i++)
+ XtUnmapWidget(computer.screens[i]->widget);
+ }
+ else if (config_mode == CONFIG_MODELINE) {
+ VideoModeConfigureEnd();
+ XtSetSensitive(layout, True);
+ XtSetSensitive(layoutm, True);
+ }
+ else if (config_mode == CONFIG_ACCESSX) {
+ AccessXConfigureEnd();
+ XtSetSensitive(layout, True);
+ XtSetSensitive(layoutm, True);
+ }
+
+ config_mode = mode;
+ XClearWindow(XtDisplay(work), XtWindow(work));
+ if (mode == CONFIG_LAYOUT) {
+ for (i = 0; i < computer.num_devices; i++)
+ XtMapWidget(computer.devices[i]->widget);
+ XtSetArg(args[0], XtNheight, height);
+ XtSetArg(args[1], XtNmin, height);
+ XtSetArg(args[2], XtNmax, height);
+ XtSetValues(commands, args, 3);
+ XtMapWidget(commands);
+ XtMapWidget(computer.cpu);
+ XtSetSensitive(commands, True);
+ DrawCables();
+ }
+ else if (mode == CONFIG_SCREEN) {
+ for (i = 0; i < computer.num_screens; i++)
+ XtMapWidget(computer.screens[i]->widget);
+ ScreenSetup(True);
+ }
+ else if (mode == CONFIG_MODELINE) {
+ VideoModeConfigureStart();
+ XtSetSensitive(layout, False);
+ XtSetSensitive(layoutm, False);
+ }
+ else if (mode == CONFIG_ACCESSX) {
+ AccessXConfigureStart();
+ XtSetSensitive(layout, False);
+ XtSetSensitive(layoutm, False);
+ }
+}
+
+static void
+ScreenSetup(Bool check)
+{
+ if (check) {
+ int i;
+
+ for (i = 0; i < computer.num_layouts; i++)
+ if (computer.layouts[i]->layout == computer.layout)
+ break;
+
+ /* Just to put the screens in the correct positions */
+ if (i >= computer.num_layouts)
+ AdjustScreenUI();
+ }
+
+ UpdateScreenUI();
+ AdjustScreenUI();
+}
diff --git a/hw/xfree86/utils/xorgcfg/keyboard-cfg.c b/hw/xfree86/utils/xorgcfg/keyboard-cfg.c
new file mode 100644
index 000000000..87989fdc2
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/keyboard-cfg.c
@@ -0,0 +1,1379 @@
+/*
+ * 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/keyboard-cfg.c,v 1.22 2003/01/01 19:22:24 paulo Exp $
+ */
+
+#include "xf86config.h"
+#include "keyboard-cfg.h"
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/MenuButton.h>
+#include <X11/Xaw/SimpleMenu.h>
+#include <X11/Xaw/SmeBSB.h>
+
+/*
+ * Types
+ */
+typedef struct {
+ char *rules;
+ XkbRF_RulesPtr list;
+ XF86XkbDescInfo model;
+ XF86XkbDescInfo layout;
+ XF86XkbDescInfo variant;
+ XF86XkbDescInfo option;
+} XF86XkbRulesDescInfo;
+
+/*
+ * Prototypes
+ */
+static void KeyboardRulesCallback(Widget, XtPointer, XtPointer);
+static void KeyboardModelCallback(Widget, XtPointer, XtPointer);
+static void KeyboardLayoutCallback(Widget, XtPointer, XtPointer);
+static void KeyboardVariantCallback(Widget, XtPointer, XtPointer);
+static void KeyboardOptionsCallback(Widget, XtPointer, XtPointer);
+static void KeyboardApplyCallback(Widget, XtPointer, XtPointer);
+static Bool KeyboardConfigCheck(void);
+static void XkbUIEventHandler(Widget, XtPointer, XEvent*, Boolean*);
+static XF86XkbRulesDescInfo *GetXkbRulesDesc(char*);
+static void UpdateRulesPopups(void);
+
+/*
+ * Initialization
+ */
+static XF86XkbRulesDescInfo **xkb_desc, *xkb_rules;
+static int num_xkb_desc;
+static char *XkbRulesDir = "lib/X11/xkb/rules/";
+#ifdef XFREE98_XKB
+static char *XkbRulesFile = "xfree98";
+#else
+static char *XkbRulesFile = "xfree86";
+#endif
+static XF86ConfInputPtr current_input;
+
+static char *rules, *model, *layout, *variant, *options;
+static Widget kbd, rulesb, modelb, layoutb, variantb, optionsb,
+ modelp, layoutp, variantp, optionsp;
+static XkbInfo **xkb_infos;
+static int num_xkb_infos;
+XkbInfo *xkb_info;
+
+static Widget apply;
+
+/*
+ * Implementation
+ */
+/*ARGSUSED*/
+XtPointer
+KeyboardConfig(XtPointer config)
+{
+ XF86ConfInputPtr keyboard = (XF86ConfInputPtr)config;
+ XF86OptionPtr option;
+ Arg args[1];
+ static char *XkbRules = "XkbRules", *XkbModel = "XkbModel",
+ *XkbLayout = "XkbLayout", *XkbVariant = "XkbVariant",
+ *XkbOptions = "XkbOptions";
+ XF86XkbRulesDescInfo *info;
+ char *omodel, *olayout, *ovariant, *ooptions;
+
+ InitializeKeyboard();
+ rules = xkb_rules->rules;
+ if (xkb_info->config.rules_file == NULL)
+ xkb_info->config.rules_file = rules;
+
+ if (options)
+ XtFree(options);
+ options = NULL;
+
+ if (xkb_info->conf == NULL)
+ xkb_info->conf = keyboard;
+
+ if (xkb_info->conf != keyboard) {
+ int i;
+
+ for (i = 0; i < num_xkb_infos; i++)
+ if (xkb_infos[i]->conf == keyboard) {
+ xkb_info = xkb_infos[i];
+ break;
+ }
+
+ if (i >= num_xkb_infos) {
+ int timeout = 10;
+
+ xkb_info = (XkbInfo*)XtCalloc(1, sizeof(XkbInfo));
+ xkb_info->conf = keyboard;
+ xkb_infos = (XkbInfo**)
+ XtRealloc((XtPointer)xkb_infos, sizeof(XkbInfo*) *
+ (num_xkb_infos + 1));
+ xkb_infos[num_xkb_infos++] = xkb_info;
+
+ xkb_info->conf = keyboard;
+ bzero((char*)&(xkb_info->defs), sizeof(XkbRF_VarDefsRec));
+ while (timeout > 0) {
+ xkb_info->xkb =
+ XkbGetKeyboard(XtDisplay(configp),
+ XkbGBN_AllComponentsMask, XkbUseCoreKbd);
+ if (xkb_info->xkb == NULL) {
+ timeout -= 1;
+ sleep(1);
+ }
+ else
+ break;
+ }
+ if (timeout <= 0) {
+ fprintf(stderr, "Couldn't get keyboard\n");
+ }
+ if (xkb_info->xkb && xkb_info->xkb->names && xkb_info->xkb->geom &&
+ xkb_info->xkb->names->geometry == 0)
+ xkb_info->xkb->names->geometry = xkb_info->xkb->geom->name;
+ }
+
+ /* check for removed devices */
+ for (i = 0; i < num_xkb_infos; i++) {
+ XF86ConfInputPtr key = XF86Config->conf_input_lst;
+
+ while (key != NULL) {
+ if (strcasecmp(key->inp_driver, "keyboard") == 0 &&
+ xkb_infos[i]->conf == key)
+ break;
+ key = (XF86ConfInputPtr)(key->list.next);
+ }
+ if (xkb_infos[i]->conf != NULL && key == NULL) {
+ XkbFreeKeyboard(xkb_infos[i]->xkb, 0, False);
+ XtFree((XtPointer)xkb_infos[i]);
+ if (--num_xkb_infos > i)
+ memmove(&xkb_infos[i], &xkb_infos[i + 1],
+ (num_xkb_infos - i) * sizeof(XkbInfo*));
+ }
+ }
+ }
+
+ current_input = keyboard;
+
+ if (keyboard != NULL) {
+ if ((option = xf86findOption(keyboard->inp_option_lst, XkbRules)) != NULL) {
+ if (strcmp(rules, option->opt_val)) {
+ XF86XkbRulesDescInfo *info = GetXkbRulesDesc(option->opt_val);
+
+ if (info) {
+ rules = info->rules;
+ UpdateRulesPopups();
+ }
+ }
+ }
+ if ((option = xf86findOption(keyboard->inp_option_lst, XkbModel)) != NULL)
+ xkb_info->defs.model = model = option->opt_val;
+ else
+ xkb_info->defs.model = model = xkb_rules->model.name[0];
+ if ((option = xf86findOption(keyboard->inp_option_lst, XkbLayout)) != NULL)
+ xkb_info->defs.layout = layout = option->opt_val;
+ else
+ xkb_info->defs.layout = layout = xkb_rules->layout.name[0];
+ if ((option = xf86findOption(keyboard->inp_option_lst, XkbVariant)) != NULL)
+ xkb_info->defs.variant = variant = option->opt_val;
+ else
+ xkb_info->defs.variant = variant = NULL;
+
+ if ((option = xf86findOption(keyboard->inp_option_lst, XkbOptions)) != NULL)
+ xkb_info->defs.options = options = XtNewString(option->opt_val);
+ else
+ xkb_info->defs.options = options = NULL;
+
+ XtSetArg(args[0], XtNstring, keyboard->inp_identifier);
+ XtSetValues(ident_widget, args, 1);
+
+ (void)UpdateKeyboard(False);
+ }
+ else {
+ XF86ConfInputPtr input = XF86Config->conf_input_lst;
+ char keyboard_name[48];
+ int nkeyboards = 0;
+
+ while (input != NULL) {
+ if (strcasecmp(input->inp_driver, "keyboard") == 0)
+ ++nkeyboards;
+ input = (XF86ConfInputPtr)(input->list.next);
+ }
+ do {
+ XmuSnprintf(keyboard_name, sizeof(keyboard_name),
+ "Keyboard%d", nkeyboards);
+ ++nkeyboards;
+ } while (xf86findInput(keyboard_name,
+ XF86Config->conf_input_lst));
+
+ model = xkb_rules->model.name[0];
+ layout = xkb_rules->layout.name[0];
+ variant = "";
+ options = XtNewString("");
+ XtSetArg(args[0], XtNstring, keyboard_name);
+ XtSetValues(ident_widget, args, 1);
+ }
+
+ info = xkb_rules;
+ omodel = model;
+ olayout = layout;
+ ovariant = variant;
+ ooptions = options ? XtNewString(options) : NULL;
+
+ xf86info.cur_list = KEYBOARD;
+ XtSetSensitive(back, xf86info.lists[KEYBOARD].cur_function > 0);
+ XtSetSensitive(next, xf86info.lists[KEYBOARD].cur_function <
+ xf86info.lists[KEYBOARD].num_functions - 1);
+ (xf86info.lists[KEYBOARD].functions[xf86info.lists[KEYBOARD].cur_function])
+ (&xf86info);
+
+ if (ConfigLoop(KeyboardConfigCheck) == True) {
+ if (keyboard == NULL) {
+ keyboard = XtNew(XF86ConfInputRec);
+ keyboard->list.next = NULL;
+ keyboard->inp_identifier = XtNewString(ident_string);
+ keyboard->inp_driver = XtNewString("keyboard");
+ keyboard->inp_option_lst = xf86newOption(XtNewString(XkbRules),
+ XtNewString(rules));
+ xf86addNewOption(keyboard->inp_option_lst,
+ XtNewString(XkbModel), XtNewString(model));
+ xf86addNewOption(keyboard->inp_option_lst,
+ XtNewString(XkbLayout), XtNewString(layout));
+ if (variant && *variant)
+ xf86addNewOption(keyboard->inp_option_lst,
+ XtNewString(XkbVariant), XtNewString(variant));
+ if (options && *options) {
+ xf86addNewOption(keyboard->inp_option_lst,
+ XtNewString(XkbOptions), options);
+ options = NULL;
+ }
+ keyboard->inp_comment = NULL;
+ }
+ else {
+ int i;
+ char *str;
+
+ XtSetArg(args[0], XtNlabel, &str);
+ XtGetValues(modelb, args, 1);
+ for (i = 0; i < xkb_rules->model.nelem; i++)
+ if (strcmp(xkb_rules->model.desc[i], str) == 0) {
+ model = xkb_rules->model.name[i];
+ break;
+ }
+
+ XtSetArg(args[0], XtNlabel, &str);
+ XtGetValues(layoutb, args, 1);
+ for (i = 0; i < xkb_rules->layout.nelem; i++)
+ if (strcmp(xkb_rules->layout.desc[i], str) == 0) {
+ layout = xkb_rules->layout.name[i];
+ break;
+ }
+
+ if ((option = xf86findOption(keyboard->inp_option_lst, XkbRules))
+ != NULL) {
+ XtFree(option->opt_val);
+ option->opt_val = XtNewString(rules);
+ XtFree(option->opt_comment);
+ option->opt_comment = NULL;
+ }
+ else
+ keyboard->inp_option_lst =
+ xf86addNewOption(keyboard->inp_option_lst,
+ XtNewString(XkbRules), XtNewString(rules));
+
+ if ((option = xf86findOption(keyboard->inp_option_lst, XkbModel))
+ != NULL) {
+ XtFree(option->opt_val);
+ option->opt_val = XtNewString(model);
+ XtFree(option->opt_comment);
+ option->opt_comment = NULL;
+ }
+ else
+ keyboard->inp_option_lst =
+ xf86addNewOption(keyboard->inp_option_lst,
+ XtNewString(XkbModel), XtNewString(model));
+ XtFree(xkb_info->config.model);
+ xkb_info->config.model = XtNewString(model);
+
+ if ((option = xf86findOption(keyboard->inp_option_lst, XkbLayout))
+ != NULL) {
+ XtFree(option->opt_val);
+ option->opt_val = XtNewString(layout);
+ }
+ else
+ keyboard->inp_option_lst =
+ xf86addNewOption(keyboard->inp_option_lst,
+ XtNewString(XkbLayout), XtNewString(layout));
+ XtFree(xkb_info->config.layout);
+ xkb_info->config.layout = XtNewString(layout);
+
+ if ((option = xf86findOption(keyboard->inp_option_lst, XkbVariant))
+ != NULL) {
+ if (variant && *variant) {
+ XtFree(option->opt_val);
+ option->opt_val = XtNewString(variant);
+ }
+ else
+ xf86removeOption(&keyboard->inp_option_lst, XkbVariant);
+ }
+ else if (variant && *variant)
+ xf86addNewOption(keyboard->inp_option_lst,
+ XtNewString(XkbVariant), XtNewString(variant));
+ XtFree(xkb_info->config.variant);
+ xkb_info->config.variant = variant && *variant ?
+ XtNewString(variant) : NULL;
+
+ XtFree(xkb_info->config.options);
+ xkb_info->config.options = options && *options ?
+ XtNewString(options) : NULL;
+ if ((option = xf86findOption(keyboard->inp_option_lst, XkbOptions))
+ != NULL) {
+ if (options && *options) {
+ XtFree(option->opt_val);
+ option->opt_val = options;
+ options = NULL;
+ }
+ else
+ xf86removeOption(&keyboard->inp_option_lst, XkbOptions);
+ }
+ else if (options && *options) {
+ xf86addNewOption(keyboard->inp_option_lst,
+ XtNewString(XkbOptions), options);
+ options = NULL;
+ }
+ }
+ if (strcasecmp(keyboard->inp_identifier, ident_string))
+ xf86renameInput(XF86Config, keyboard, ident_string);
+
+ xkb_info->conf = keyboard;
+ xkb_info->config.rules_file = rules;
+
+ return ((XtPointer)keyboard);
+ }
+
+ xkb_rules = info;
+ rules = info->rules;
+ model = omodel;
+ layout = olayout;
+ variant = ovariant;
+ XtFree(options);
+ options = ooptions;
+
+ return (NULL);
+}
+
+static Bool
+KeyboardConfigCheck(void)
+{
+ XF86ConfInputPtr keyboard = XF86Config->conf_input_lst;
+
+ while (keyboard != NULL) {
+ if (keyboard != current_input &&
+ strcasecmp(ident_string, keyboard->inp_identifier) == 0)
+ return (False);
+ keyboard = (XF86ConfInputPtr)(keyboard->list.next);
+ }
+
+ return (True);
+}
+
+/*ARGSUSED*/
+static void
+XkbUIEventHandler(Widget w, XtPointer closure,
+ XEvent *event, Boolean *continue_to_dispatch)
+{
+ XkbUI_ViewOptsRec opts;
+ XkbUI_ViewPtr view;
+ int width, height, bd;
+
+ if (event->xexpose.count > 1)
+ return;
+
+ bzero((char *)&opts, sizeof(opts));
+ bd = 1;
+ opts.present = XkbUI_SizeMask | XkbUI_ColormapMask |
+ XkbUI_MarginMask | XkbUI_OffsetMask;
+ opts.margin_width = opts.margin_height = 0;
+ opts.viewport.x = opts.viewport.y = bd;
+ width = opts.viewport.width = w->core.width - 2 * bd;
+ height = opts.viewport.height = w->core.height - 2 * bd;
+ opts.cmap = w->core.colormap;
+
+ if ((view = XkbUI_Init(XtDisplay(w), XtWindow(w), width, height,
+ xkb_info->xkb, &opts)) != NULL) {
+ XkbUI_DrawRegion(view, NULL);
+ free(view);
+ }
+}
+
+void
+InitializeKeyboard(void)
+{
+ int major, minor, op, event, error;
+ static int first = 1;
+ int timeout = 5;
+ XF86ConfInputPtr keyboard = XF86Config->conf_input_lst;
+ XF86OptionPtr option;
+ char name[PATH_MAX];
+ FILE *file;
+
+ if (!first)
+ return;
+ first = 0;
+
+ major = XkbMajorVersion;
+ minor = XkbMinorVersion;
+ if (XkbQueryExtension(DPY, &op, &event, &error, &major, &minor) == 0) {
+ fprintf(stderr, "Unable to initialize XKEYBOARD extension");
+ exit(1);
+ }
+
+ xkb_info = (XkbInfo *)XtCalloc(1, sizeof(XkbInfo));
+ xkb_info->conf = NULL;
+ xkb_infos = (XkbInfo**)XtCalloc(1, sizeof(XkbInfo*));
+ num_xkb_infos = 1;
+ xkb_infos[0] = xkb_info;
+ bzero((char*)&(xkb_info->defs), sizeof(XkbRF_VarDefsRec));
+
+ while (timeout > 0) {
+ xkb_info->xkb =
+ XkbGetKeyboard(DPY, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
+ if (xkb_info->xkb == NULL) {
+ timeout -= 1;
+ sleep(1);
+ }
+ else
+ break;
+ }
+ if (timeout <= 0) {
+ fprintf(stderr, "Couldn't get keyboard\n");
+ }
+ if (xkb_info->xkb && xkb_info->xkb->names && xkb_info->xkb->geom &&
+ xkb_info->xkb->names->geometry == 0)
+ xkb_info->xkb->names->geometry = xkb_info->xkb->geom->name;
+
+ /* Load configuration */
+ XmuSnprintf(name, sizeof(name), "%s%s", XkbConfigDir, XkbConfigFile);
+ file = fopen(name, "r");
+ if (file != NULL) {
+ if (XkbCFParse(file, XkbCFDflts, xkb_info->xkb, &xkb_info->config) == 0) {
+ fprintf(stderr, "Error parsing config file: ");
+ XkbCFReportError(stderr, name, xkb_info->config.error,
+ xkb_info->config.line);
+ }
+ fclose(file);
+ }
+
+ xkb_rules = GetXkbRulesDesc(xkb_info->config.rules_file != NULL ?
+ xkb_info->config.rules_file : XkbRulesFile);
+ if (xkb_rules == NULL)
+ /* error message was printed */
+ exit(1);
+
+ /* XXX Assumes the first keyboard is the core keyboard */
+ while (keyboard != NULL) {
+ if (strcasecmp(keyboard->inp_driver, "keyboard") == 0)
+ break;
+ keyboard = (XF86ConfInputPtr)(keyboard->list.next);
+ }
+ if (keyboard == NULL)
+ return;
+
+ if (xkb_info->config.rules_file != NULL)
+ rules = xkb_info->config.rules_file;
+ else if ((option = xf86findOption(keyboard->inp_option_lst, "XkbRules"))
+ != NULL)
+ rules = option->opt_val;
+ else
+ rules = XkbRulesFile;
+
+ if (strcmp(rules, xkb_rules->rules)) {
+ xkb_rules = GetXkbRulesDesc(rules);
+ if (xkb_rules == NULL)
+ /* error message was printed */
+ exit(1);
+ }
+ {
+ FILE *fp;
+ char filename[1024];
+
+ XmuSnprintf(filename, sizeof(filename), "%s%s",
+ XkbRulesDir, xkb_rules->rules);
+ if ((fp = fopen(filename, "r")) == NULL) {
+ fprintf(stderr, "Can't open rules file\n");
+ exit(1);
+ }
+
+ if (!XkbRF_LoadRules(fp, xkb_rules->list)) {
+ fclose(fp);
+ fprintf(stderr, "Can't load rules\n");
+ exit(1);
+ }
+ fclose(fp);
+ }
+
+ if (xkb_info->config.rules_file == NULL)
+ xkb_info->config.rules_file = xkb_rules->rules;
+
+ if (xkb_info->config.model != NULL)
+ xkb_info->defs.model = xkb_info->config.model;
+ else if ((option = xf86findOption(keyboard->inp_option_lst, "XkbModel"))
+ != NULL)
+ xkb_info->defs.model = option->opt_val;
+ else
+ xkb_info->defs.model = xkb_rules->model.name[0];
+
+ if (xkb_info->config.layout != NULL)
+ xkb_info->defs.layout = xkb_info->config.layout;
+ else if ((option = xf86findOption(keyboard->inp_option_lst, "XkbLayout"))
+ != NULL)
+ xkb_info->defs.layout = option->opt_val;
+ else
+ xkb_info->defs.layout = xkb_rules->layout.name[0];
+
+ if (xkb_info->config.variant != NULL)
+ xkb_info->defs.variant = xkb_info->config.variant;
+ else if ((option = xf86findOption(keyboard->inp_option_lst, "XkbVariant"))
+ != NULL)
+ xkb_info->defs.variant = option->opt_val;
+ else
+ xkb_info->defs.variant = NULL;
+
+ if (xkb_info->config.options != NULL)
+ xkb_info->defs.options = xkb_info->config.options;
+ else if ((option = xf86findOption(keyboard->inp_option_lst, "XkbOptions"))
+ != NULL)
+ xkb_info->defs.options = option->opt_val;
+ else
+ xkb_info->defs.options = NULL;
+
+ if (xkb_info->xkb == NULL) {
+ /* Try again */
+ XkbComponentNamesRec comps;
+
+ bzero((char*)&comps, sizeof(XkbComponentNamesRec));
+ XkbRF_GetComponents(xkb_rules->list, &(xkb_info->defs), &comps);
+
+ xkb_info->xkb = XkbGetKeyboardByName(DPY, XkbUseCoreKbd, &comps,
+ XkbGBN_AllComponentsMask, 0, 0);
+ }
+}
+
+static XF86XkbRulesDescInfo *
+GetXkbRulesDesc(char *rules)
+{
+ int i;
+ XkbRF_RulesPtr list;
+ char filename[1024];
+ XF86XkbRulesDescInfo *info;
+
+ if (rules == NULL)
+ return (NULL);
+
+ for (i = 0; i < num_xkb_desc; i++)
+ if (strcmp(rules, xkb_desc[i]->rules) == 0)
+ return (xkb_desc[i]);
+
+ XmuSnprintf(filename, sizeof(filename), "%s%s", XkbRulesDir, rules);
+ if ((list = XkbRF_Create(0, 0)) == NULL ||
+ !XkbRF_LoadDescriptionsByName(filename, NULL, list)) {
+ fprintf(stderr, "Can't create rules structure\n");
+ return (NULL);
+ }
+
+ info = (XF86XkbRulesDescInfo*)XtCalloc(1, sizeof(XF86XkbRulesDescInfo));
+ xkb_desc = (XF86XkbRulesDescInfo**)
+ XtRealloc((XtPointer)xkb_desc,
+ sizeof(XF86XkbRulesDescInfo*) * (num_xkb_desc + 1));
+ xkb_desc[num_xkb_desc++] = info;
+ info->rules = XtNewString(rules);
+ for (i = 0; i < list->models.num_desc; i++) {
+ if (i % 16 == 0) {
+ info->model.name = (char**)XtRealloc((XtPointer)info->model.name,
+ (i + 16) * sizeof(char*));
+ info->model.desc = (char**)XtRealloc((XtPointer)info->model.desc,
+ (i + 16) * sizeof(char*));
+ }
+ info->model.name[i] = XtNewString(list->models.desc[i].name);
+ info->model.desc[i] = XtNewString(list->models.desc[i].desc);
+ }
+ info->model.nelem = i;
+
+ for (i = 0; i < list->layouts.num_desc; i++) {
+ if (i % 16 == 0) {
+ info->layout.name = (char**)XtRealloc((XtPointer)info->layout.name,
+ (i + 16) * sizeof(char*));
+ info->layout.desc = (char**)XtRealloc((XtPointer)info->layout.desc,
+ (i + 16) * sizeof(char*));
+ }
+ info->layout.name[i] = XtNewString(list->layouts.desc[i].name);
+ info->layout.desc[i] = XtNewString(list->layouts.desc[i].desc);
+ }
+ info->layout.nelem = i;
+
+ for (i = 0; i < list->variants.num_desc; i++) {
+ if (i % 16 == 0) {
+ info->variant.name = (char**)XtRealloc((XtPointer)info->variant.name,
+ (i + 16) * sizeof(char*));
+ info->variant.desc = (char**)XtRealloc((XtPointer)info->variant.desc,
+ (i + 16) * sizeof(char*));
+ }
+ info->variant.name[i] = XtNewString(list->variants.desc[i].name);
+ info->variant.desc[i] = XtNewString(list->variants.desc[i].desc);
+ }
+ info->variant.nelem = i;
+
+ for (i = 0; i < list->options.num_desc; i++) {
+ if (i % 16 == 0) {
+ info->option.name = (char**)XtRealloc((XtPointer)info->option.name,
+ (i + 16) * sizeof(char*));
+ info->option.desc = (char**)XtRealloc((XtPointer)info->option.desc,
+ (i + 16) * sizeof(char*));
+ }
+ info->option.name[i] = XtNewString(list->options.desc[i].name);
+ info->option.desc[i] = XtNewString(list->options.desc[i].desc);
+ }
+ info->option.nelem = i;
+ info->list = list;
+
+ return (info);
+}
+
+static xf86ConfigSymTabRec ax_controls[] =
+{
+ {XkbRepeatKeysMask, "RepeatKeys"},
+ {XkbSlowKeysMask, "SlowKeys"},
+ {XkbBounceKeysMask, "BounceKeys"},
+ {XkbStickyKeysMask, "StickyKeys"},
+ {XkbMouseKeysMask, "MouseKeys"},
+ {XkbMouseKeysAccelMask, "MouseKeysAccel"},
+ {XkbAccessXKeysMask, "AccessxKeys"},
+ {XkbAccessXTimeoutMask, "AccessxTimeout"},
+ {XkbAccessXFeedbackMask, "AccessxFeedback"},
+ {XkbAudibleBellMask, "AudibleBell"},
+ {XkbOverlay1Mask, "Overlay1"},
+ {XkbOverlay2Mask, "Overlay2"},
+ {XkbIgnoreGroupLockMask, "IgnoreGroupLock"},
+ {-1, ""},
+};
+
+static xf86ConfigSymTabRec ax_feedback[] =
+{
+ {XkbAX_SKPressFBMask, "SlowKeysPress"},
+ {XkbAX_SKAcceptFBMask, "SlowKeysAccept"},
+ {XkbAX_FeatureFBMask, "Feature"},
+ {XkbAX_SlowWarnFBMask, "SlowWarn"},
+ {XkbAX_IndicatorFBMask, "Indicator"},
+ {XkbAX_StickyKeysFBMask, "StickyKeys"},
+ {XkbAX_TwoKeysMask, "TwoKeys"},
+ {XkbAX_LatchToLockMask, "LatchToLock"},
+ {XkbAX_SKReleaseFBMask, "SlowKeysRelease"},
+ {XkbAX_SKRejectFBMask, "SlowkeysReject"},
+ {XkbAX_BKRejectFBMask, "BounceKeysReject"},
+ {XkbAX_DumbBellFBMask, "DumbBell"},
+ {-1, ""},
+};
+
+Bool
+WriteXKBConfiguration(char *filename, XkbConfigRtrnPtr conf)
+{
+ FILE *fp;
+ int i, count;
+
+ if (filename == NULL || conf == NULL ||
+ (fp = fopen(filename, "w")) == NULL)
+ return (False);
+
+ if (conf->rules_file != NULL)
+ fprintf(fp, "Rules = \"%s\"\n",
+ conf->rules_file);
+ if (conf->model != NULL)
+ fprintf(fp, "Model = \"%s\"\n",
+ conf->model);
+ if (conf->layout != NULL)
+ fprintf(fp, "Layout = \"%s\"\n",
+ conf->layout);
+ if (conf->variant != NULL)
+ fprintf(fp, "Variant = \"%s\"\n",
+ conf->variant);
+ if (conf->options != NULL)
+ fprintf(fp, "Options = \"%s\"\n",
+ conf->options);
+ if (conf->keymap != NULL)
+ fprintf(fp, "Keymap = %s\n",
+ conf->keymap);
+ if (conf->keycodes != NULL)
+ fprintf(fp, "Keycodes = %s\n",
+ conf->keycodes);
+ if (conf->geometry != NULL)
+ fprintf(fp, "Geometry = %s\n",
+ conf->geometry);
+ if (conf->phys_symbols != NULL)
+ fprintf(fp, "RealSymbols = %s\n",
+ conf->phys_symbols);
+ if (conf->symbols != NULL)
+ fprintf(fp, "Symbols = %s\n",
+ conf->symbols);
+ if (conf->types != NULL)
+ fprintf(fp, "Types = %s\n",
+ conf->types);
+ if (conf->compat != NULL)
+ fprintf(fp, "Compat = %s\n",
+ conf->compat);
+
+ if (conf->click_volume > 0)
+ fprintf(fp, "ClickVolume = %d\n",
+ conf->click_volume);
+ if (conf->bell_volume > 0)
+ fprintf(fp, "BellVolume = %d\n",
+ conf->bell_volume);
+ if (conf->bell_pitch > 0)
+ fprintf(fp, "BellPitch = %d\n",
+ conf->bell_pitch);
+ if (conf->bell_duration > 0)
+ fprintf(fp, "BellDuration = %d\n",
+ conf->bell_duration);
+
+ if (conf->repeat_delay > 0)
+ fprintf(fp, "RepeatDelay = %d\n",
+ conf->repeat_delay);
+ if (conf->repeat_interval > 0)
+ fprintf(fp, "RepeatInterval = %d\n",
+ conf->repeat_interval);
+
+ if (conf->slow_keys_delay > 0)
+ fprintf(fp, "SlowKeysDelay = %d\n",
+ conf->slow_keys_delay);
+
+ if (conf->debounce_delay > 0)
+ fprintf(fp, "DebounceDelay = %d\n",
+ conf->debounce_delay);
+
+ if (conf->mk_delay > 0)
+ fprintf(fp, "MouseKeysDelay = %d\n",
+ conf->mk_delay);
+ if (conf->mk_interval > 0)
+ fprintf(fp, "MouseKeysInterval = %d\n",
+ conf->mk_interval);
+ if (conf->mk_time_to_max > 0)
+ fprintf(fp, "MouseKeysTimeToMax = %d\n",
+ conf->mk_time_to_max);
+ if (conf->mk_max_speed > 0)
+ fprintf(fp, "MouseKeysMaxSpeed = %d\n",
+ conf->mk_max_speed);
+ fprintf(fp, "MouseKeysCurve = %d\n", conf->mk_curve);
+
+ if (conf->ax_timeout)
+ fprintf(fp, "AccessXTimeout = %d\n",
+ conf->ax_timeout);
+ if (conf->initial_ctrls != 0) {
+ fprintf(fp, "Controls %c= ",
+ conf->replace_initial_ctrls ? ' ' : '+');
+ for (i = count = 0; *ax_controls[i].name; i++)
+ if ((conf->initial_ctrls & ax_controls[i].token)
+ == ax_controls[i].token)
+ fprintf(fp, "%s%s", count++ ? " + " : "",
+ ax_controls[i].name);
+ fprintf(fp, "\n");
+ }
+ if (conf->axt_ctrls_on != 0) {
+ fprintf(fp, "AcessXTimeoutCtrlsOn %c= ",
+ conf->replace_axt_ctrls_on ? ' ' : '+');
+ for (i = count = 0; *ax_controls[i].name; i++)
+ if ((conf->axt_ctrls_on & ax_controls[i].token)
+ == ax_controls[i].token)
+ fprintf(fp, "%s%s", count++ ? " + " : "",
+ ax_controls[i].name);
+ fprintf(fp, "\n");
+ }
+ if (conf->axt_ctrls_off != 0) {
+ fprintf(fp, "AcessXTimeoutCtrlsOff %c= ",
+ conf->replace_axt_ctrls_off ? ' ' : '-');
+ for (i = count = 0; *ax_controls[i].name; i++)
+ if ((conf->axt_ctrls_off & ax_controls[i].token)
+ == ax_controls[i].token)
+ fprintf(fp, "%s%s", count++ ? " + " : "",
+ ax_controls[i].name);
+ fprintf(fp, "\n");
+ }
+
+ if (conf->initial_opts != 0) {
+ fprintf(fp, "Feedback %c= ",
+ conf->replace_initial_opts ? ' ' : '+');
+ for (i = count = 0; *ax_feedback[i].name; i++)
+ if ((conf->initial_opts & ax_feedback[i].token)
+ == ax_feedback[i].token)
+ fprintf(fp, "%s%s", count++ ? " + " : "",
+ ax_feedback[i].name);
+ fprintf(fp, "\n");
+ }
+ if (conf->axt_opts_on != 0) {
+ fprintf(fp, "AcessXTimeoutFeedbackOn %c= ",
+ conf->replace_axt_opts_on ? ' ' : '+');
+ for (i = count = 0; *ax_controls[i].name; i++)
+ if ((conf->axt_opts_on & ax_feedback[i].token)
+ == ax_feedback[i].token)
+ fprintf(fp, "%s%s", count++ ? " + " : "",
+ ax_feedback[i].name);
+ fprintf(fp, "\n");
+ }
+ if (conf->axt_opts_off != 0) {
+ fprintf(fp, "AcessXTimeoutFeedbackOff%c= ",
+ conf->replace_axt_opts_off ? ' ' : '-');
+ for (i = count = 0; *ax_feedback[i].name; i++)
+ if ((conf->axt_opts_off & ax_feedback[i].token)
+ == ax_feedback[i].token)
+ fprintf(fp, "%s%s", count++ ? " + " : "",
+ ax_feedback[i].name);
+ fprintf(fp, "\n");
+ }
+
+ fclose(fp);
+
+ return (True);
+}
+
+Bool
+UpdateKeyboard(Bool load)
+{
+ XkbComponentNamesRec comps;
+ XkbDescPtr xkb;
+
+ bzero((char*)&comps, sizeof(XkbComponentNamesRec));
+ XkbRF_GetComponents(xkb_rules->list, &(xkb_info->defs), &comps);
+
+ xkb = XkbGetKeyboardByName(DPY, XkbUseCoreKbd, &comps,
+ XkbGBN_AllComponentsMask, 0, load);
+
+ if (xkb == NULL || xkb->geom == NULL) {
+ fprintf(stderr, "Couldn't get keyboard\n");
+ return (False);
+ }
+ if (xkb_info->xkb && xkb_info->xkb->names && xkb_info->xkb->geom &&
+ xkb_info->xkb->names->geometry == 0)
+ xkb_info->xkb->names->geometry = xkb_info->xkb->geom->name;
+
+ XkbFreeKeyboard(xkb_info->xkb, 0, False);
+
+ xkb_info->xkb = xkb;
+
+ XtFree(comps.keymap);
+ XtFree(comps.keycodes);
+ XtFree(comps.compat);
+ XtFree(comps.types);
+ XtFree(comps.symbols);
+ XtFree(comps.geometry);
+
+ if (kbd != NULL)
+ XClearArea(XtDisplay(configp), XtWindow(kbd), 0, 0, 0, 0, True);
+
+ return (True);
+}
+
+static void
+KeyboardRulesCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ int i;
+ FILE *fp;
+ Arg args[1];
+ char filename[1024], *omodel, *olayout, *ovariant, *ooptions,
+ *dmodel, *dlayout, *dvariant;
+ XF86XkbRulesDescInfo *oxkb_rules, *info = GetXkbRulesDesc(XtName(w));
+
+ if (strcmp(XtName(w), rules) == 0 || info == NULL)
+ /* a error message was printed */
+ return;
+
+ XmuSnprintf(filename, sizeof(filename), "%s%s",
+ XkbRulesDir, info->rules);
+ if ((fp = fopen(filename, "r")) == NULL) {
+ fprintf(stderr, "Can't open rules file\n");
+ return;
+ }
+
+ if (!XkbRF_LoadRules(fp, info->list)) {
+ fclose(fp);
+ fprintf(stderr, "Can't load rules\n");
+ return;
+ }
+ fclose(fp);
+
+ oxkb_rules = xkb_rules;
+ omodel = xkb_info->defs.model;
+ olayout = xkb_info->defs.layout;
+ ovariant = xkb_info->defs.variant;
+ ooptions = xkb_info->defs.options;
+
+ if (omodel) {
+ for (i = 0; i < info->model.nelem; i++) {
+ if (strcmp(omodel, info->model.name[i]) == 0)
+ break;
+ }
+ }
+ else
+ i = 0;
+ model = xkb_info->defs.model = info->model.name
+ [i < info->model.nelem ? i : 0];
+ dmodel = info->model.desc[i < info->model.nelem ? i : 0];
+
+ if (olayout) {
+ for (i = 0; i < info->layout.nelem; i++) {
+ if (strcmp(olayout, info->layout.name[i]) == 0)
+ break;
+ }
+ }
+ else
+ i = 0;
+ layout = xkb_info->defs.layout = info->layout.name
+ [i < info->layout.nelem ? i : 0];
+ dlayout = info->layout.desc[i < info->layout.nelem ? i : 0];
+
+ if (ovariant) {
+ for (i = 0; i < info->variant.nelem; i++) {
+ if (strcmp(ovariant, info->variant.name[i]) == 0)
+ break;
+ }
+ }
+ else
+ i = info->variant.nelem;
+ variant = xkb_info->defs.variant = i < info->variant.nelem ?
+ info->variant.name[i] : NULL;
+ dvariant = i < info->variant.nelem ?
+ info->variant.desc[i] : NULL;
+
+ if (ooptions) {
+ char *ptr, *tmp = XtNewString(options);
+
+ for (ptr = strtok(tmp, ","); ptr != NULL; ptr = strtok(NULL, ",")) {
+ if (strchr(ptr, ':') == NULL)
+ continue;
+
+ for (i = 0; i < xkb_rules->option.nelem; i++)
+ if (strcmp(xkb_rules->option.name[i], ptr) == 0)
+ break;
+
+ if (i == xkb_rules->option.nelem) {
+ XtFree(options);
+ options = NULL;
+ /* no option with the same name */
+ break;
+ }
+ }
+ XtFree(tmp);
+ }
+ else {
+ XtFree(options);
+ options = NULL;
+ }
+
+ oxkb_rules = xkb_rules;
+ xkb_rules = info;
+ rules = info->rules;
+
+ if (!UpdateKeyboard(False)) {
+ model = xkb_info->defs.model = omodel;
+ layout = xkb_info->defs.layout = olayout;
+ variant = xkb_info->defs.variant = ovariant;
+ options = XtNewString(xkb_info->defs.options = ooptions);
+ xkb_rules = oxkb_rules;
+ rules = xkb_rules->rules;
+
+ XmuSnprintf(filename, sizeof(filename), "%s%s",
+ XkbRulesDir, rules);
+ if ((fp = fopen(filename, "r")) == NULL) {
+ fprintf(stderr, "Can't open rules file\n");
+ return;
+ }
+
+ if (!XkbRF_LoadRules(fp, xkb_rules->list)) {
+ fclose(fp);
+ fprintf(stderr, "Can't load rules\n");
+ }
+ fclose(fp);
+
+ return;
+ }
+
+ UpdateRulesPopups();
+
+ XtSetArg(args[0], XtNlabel, rules);
+ XtSetValues(rulesb, args, 1);
+
+ XtSetArg(args[0], XtNlabel, dmodel);
+ XtSetValues(modelb, args, 1);
+
+ XtSetArg(args[0], XtNlabel, dlayout);
+ XtSetValues(layoutb, args, 1);
+
+ XtSetArg(args[0], XtNlabel, dvariant ? dvariant : "");
+ XtSetValues(variantb, args, 1);
+
+ XtSetArg(args[0], XtNlabel, options ? options : "");
+ XtSetValues(variantb, args, 1);
+}
+
+static void
+KeyboardModelCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[1];
+ int i;
+ char *oldval = xkb_info->defs.model;
+
+ for (i = 0; i < xkb_rules->model.nelem; i++)
+ if (strcmp(XtName(w), xkb_rules->model.name[i]) == 0)
+ break;
+ model = xkb_info->defs.model = xkb_rules->model.name[i];
+ if (!UpdateKeyboard(False))
+ model = xkb_info->defs.model = oldval;
+ else {
+ XtSetArg(args[0], XtNlabel, xkb_rules->model.desc[i]);
+ XtSetValues(modelb, args, 1);
+ }
+}
+
+static void
+KeyboardLayoutCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[1];
+ int i;
+ char *oldval = xkb_info->defs.layout;
+
+ for (i = 0; i < xkb_rules->layout.nelem; i++)
+ if (strcmp(XtName(w), xkb_rules->layout.name[i]) == 0)
+ break;
+ layout = xkb_info->defs.layout = xkb_rules->layout.name[i];
+ if (!UpdateKeyboard(False))
+ layout = xkb_info->defs.layout = oldval;
+ else {
+ XtSetArg(args[0], XtNlabel, xkb_rules->layout.desc[i]);
+ XtSetValues(layoutb, args, 1);
+ }
+}
+
+static void
+KeyboardVariantCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[1];
+ int i;
+ char *label, *oldval = xkb_info->defs.variant;
+
+ for (i = 0; i < xkb_rules->variant.nelem; i++)
+ if (strcmp(XtName(w), xkb_rules->variant.name[i]) == 0)
+ break;
+ variant = i < xkb_rules->variant.nelem ? xkb_rules->variant.name[i] : "";
+ xkb_info->defs.variant = variant && *variant ? variant : NULL;
+
+ if (!UpdateKeyboard(False))
+ xkb_info->defs.variant = variant = oldval;
+ else {
+ label = i < xkb_rules->variant.nelem ? xkb_rules->variant.desc[i] : "";
+ XtSetArg(args[0], XtNlabel, label);
+ XtSetValues(variantb, args, 1);
+ }
+}
+
+static void
+KeyboardOptionsCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[1];
+ int i;
+
+ for (i = 0; i < xkb_rules->option.nelem; i++)
+ if (strcmp(XtName(w), xkb_rules->option.name[i]) == 0)
+ break;
+
+ if (i < xkb_rules->option.nelem) {
+ char *delim, *ptr, str[256];
+
+ /* remove old string, don't check if the same */
+ if ((delim = strchr(XtName(w), ':')) != NULL) {
+ if (delim - XtName(w) >= sizeof(str) - 2)
+ return;
+ strncpy(str, XtName(w), delim - XtName(w) + 1);
+ str[delim - XtName(w) + 1] = '\0';
+ }
+ else
+ XmuSnprintf(str, sizeof(str), "%s:", XtName(w));
+ if (options && (delim = strstr(options, str)) != NULL) {
+ if ((ptr = strchr(delim, ',')) != NULL) {
+ *delim = *ptr = '\0';
+ XmuSnprintf(str, sizeof(str), "%s%s", options, ptr + 1);
+ XtFree(options);
+ options = XtNewString(str);
+ }
+ else {
+ if (delim > options)
+ delim[-1] = '\0';
+ else
+ delim[0] = '\0';
+ }
+ }
+
+ /* update string, if required */
+ if ((delim = strchr(XtName(w), ':')) != NULL) {
+ if (options && *options)
+ XmuSnprintf(str, sizeof(str), "%s,%s", options, XtName(w));
+ else
+ XmuSnprintf(str, sizeof(str), "%s", XtName(w));
+ XtFree(options);
+ options = XtNewString(str);
+ }
+ }
+ else {
+ XtFree(options);
+ options = XtNewString("");
+ }
+
+ if (options == NULL)
+ options = XtNewString("");
+
+ xkb_info->defs.options = options;
+ if (!UpdateKeyboard(False)) {
+ *options = '\0';
+ xkb_info->defs.options = NULL;
+ }
+ XtSetArg(args[0], XtNlabel, options);
+ XtSetValues(optionsb, args, 1);
+ XtSetArg(args[0], XtNtip, options);
+ XtSetValues(optionsb, args, 1);
+}
+
+/*ARGSUSED*/
+static void
+KeyboardApplyCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ (void)UpdateKeyboard(True);
+}
+
+static void
+UpdateRulesPopups(void)
+{
+ int i;
+ char *optname;
+ Widget sme, optpopup = NULL, optparent;
+
+ /* MODEL */
+ if (modelp)
+ XtDestroyWidget(modelp);
+ modelp = XtCreatePopupShell("modelP", simpleMenuWidgetClass,
+ modelb, NULL, 0);
+ for (i = 0; i < xkb_rules->model.nelem; i++) {
+ sme = XtVaCreateManagedWidget(xkb_rules->model.name[i], smeBSBObjectClass,
+ modelp,
+ XtNlabel, xkb_rules->model.desc[i],
+ NULL, 0);
+ XtAddCallback(sme, XtNcallback, KeyboardModelCallback, NULL);
+ }
+
+ /* LAYOUT */
+ if (layoutp)
+ XtDestroyWidget(layoutp);
+ layoutp = XtCreatePopupShell("layoutP", simpleMenuWidgetClass,
+ layoutb, NULL, 0);
+ for (i = 0; i < xkb_rules->layout.nelem; i++) {
+ sme = XtVaCreateManagedWidget(xkb_rules->layout.name[i], smeBSBObjectClass,
+ layoutp,
+ XtNlabel, xkb_rules->layout.desc[i],
+ NULL, 0);
+ XtAddCallback(sme, XtNcallback, KeyboardLayoutCallback, NULL);
+ }
+
+ /* VARIANT */
+ if (variantp)
+ XtDestroyWidget(variantp);
+ variantp = XtCreatePopupShell("variantP", simpleMenuWidgetClass,
+ variantb, NULL, 0);
+ sme = XtVaCreateManagedWidget("None", smeBSBObjectClass,
+ variantp,
+ XtNlabel, "None",
+ NULL, 0);
+ XtAddCallback(sme, XtNcallback, KeyboardVariantCallback, NULL);
+ for (i = 0; i < xkb_rules->variant.nelem; i++) {
+ sme = XtVaCreateManagedWidget(xkb_rules->variant.name[i], smeBSBObjectClass,
+ variantp,
+ XtNlabel, xkb_rules->variant.desc[i],
+ NULL, 0);
+ XtAddCallback(sme, XtNcallback, KeyboardVariantCallback, NULL);
+ }
+
+ /* OPTIONS */
+ if (optionsp)
+ XtDestroyWidget(optionsp);
+ optionsp = XtCreatePopupShell("optionsP", simpleMenuWidgetClass,
+ optionsb, NULL, 0);
+ sme = XtVaCreateManagedWidget("None", smeBSBObjectClass,
+ optionsp,
+ XtNlabel, "None",
+ NULL, 0);
+ XtAddCallback(sme, XtNcallback, KeyboardOptionsCallback, NULL);
+ optparent = optionsp;
+ optname = NULL;
+ for (i = 0; i < xkb_rules->option.nelem; i++) {
+ if (!strchr(xkb_rules->option.name[i], ':')) {
+ optpopup =
+ XtCreatePopupShell(optname = xkb_rules->option.desc[i],
+ simpleMenuWidgetClass,
+ optparent = optionsp, NULL, 0);
+ sme = XtVaCreateManagedWidget(xkb_rules->option.name[i],
+ smeBSBObjectClass,
+ optpopup,
+ XtNlabel, "None",
+ NULL, 0);
+ XtAddCallback(sme, XtNcallback, KeyboardOptionsCallback, NULL);
+ }
+ else {
+ optparent = optpopup;
+ optname = NULL;
+ }
+ sme = XtVaCreateManagedWidget(xkb_rules->option.name[i], smeBSBObjectClass,
+ optparent,
+ XtNlabel, xkb_rules->option.desc[i],
+ XtNmenuName, optname,
+ XtNleftBitmap, optname ? menuPixmap : None,
+ NULL, 0);
+ if (optparent != optionsp)
+ XtAddCallback(sme, XtNcallback, KeyboardOptionsCallback, NULL);
+ }
+}
+
+void
+KeyboardModelAndLayout(XF86SetupInfo *info)
+{
+ static int first = 1;
+ static Widget kbdml;
+ Arg args[1];
+ int i;
+
+ if (first) {
+ Widget popup, sme;
+
+ first = 0;
+
+ kbdml = XtCreateWidget("keyboardML", formWidgetClass,
+ configp, NULL, 0);
+
+ /* RULES */
+ XtCreateManagedWidget("labelR", labelWidgetClass, kbdml, NULL, 0);
+ rulesb = XtVaCreateManagedWidget("rules", menuButtonWidgetClass, kbdml,
+ XtNmenuName, "rulesP",
+ NULL, 0);
+ popup = XtCreatePopupShell("rulesP", simpleMenuWidgetClass,
+ rulesb, NULL, 0);
+ {
+ struct dirent *ent;
+ DIR *dir;
+
+ if ((dir = opendir(XkbRulesDir)) != NULL) {
+ (void)readdir(dir);
+ (void)readdir(dir);
+ while ((ent = readdir(dir)) != NULL) {
+ if (strchr(ent->d_name, '.'))
+ continue;
+
+ sme = XtVaCreateManagedWidget(ent->d_name, smeBSBObjectClass,
+ popup,
+ XtNlabel, ent->d_name,
+ NULL, 0);
+ XtAddCallback(sme, XtNcallback, KeyboardRulesCallback, NULL);
+ }
+ closedir(dir);
+ }
+ }
+
+ /* MODEL */
+ XtCreateManagedWidget("labelM", labelWidgetClass, kbdml, NULL, 0);
+ modelb = XtVaCreateManagedWidget("model", menuButtonWidgetClass, kbdml,
+ XtNmenuName, "modelP",
+ NULL, 0);
+
+ /* LAYOUT */
+ XtCreateManagedWidget("labelL", labelWidgetClass, kbdml, NULL, 0);
+ layoutb = XtVaCreateManagedWidget("layout", menuButtonWidgetClass, kbdml,
+ XtNmenuName, "layoutP",
+ XtNlabel, xkb_rules->layout.desc[0],
+ NULL, 0);
+
+ /* VARIANT */
+ XtCreateManagedWidget("labelV", labelWidgetClass, kbdml, NULL, 0);
+ variantb = XtVaCreateManagedWidget("variant", menuButtonWidgetClass, kbdml,
+ XtNmenuName, "variantP",
+ XtNlabel, "",
+ NULL, 0);
+
+ /* OPTIONS */
+ XtCreateManagedWidget("labelO", labelWidgetClass, kbdml, NULL, 0);
+ optionsb = XtVaCreateManagedWidget("options", menuButtonWidgetClass, kbdml,
+ XtNmenuName, "optionsP",
+ XtNlabel, "",
+ NULL, 0);
+
+ UpdateRulesPopups();
+
+ kbd = XtCreateManagedWidget("keyboard", coreWidgetClass,
+ kbdml, NULL, 0);
+
+ apply = XtCreateManagedWidget("apply", commandWidgetClass,
+ kbdml, NULL, 0);
+ XtAddCallback(apply, XtNcallback, KeyboardApplyCallback, NULL);
+
+ XtRealizeWidget(kbdml);
+
+ XtAddEventHandler(kbd, ExposureMask, False, XkbUIEventHandler, NULL);
+ /* Force the first update */
+ XClearArea(XtDisplay(kbd), XtWindow(kbd), 0, 0, 0, 0, True);
+ }
+
+ XtSetArg(args[0], XtNlabel, xkb_rules->rules);
+ XtSetValues(rulesb, args, 1);
+
+ for (i = 0; i < xkb_rules->model.nelem; i++)
+ if (strcmp(model, xkb_rules->model.name[i]) == 0) {
+ XtSetArg(args[0], XtNlabel, xkb_rules->model.desc[i]);
+ XtSetValues(modelb, args, 1);
+ break;
+ }
+
+ for (i = 0; i < xkb_rules->layout.nelem; i++)
+ if (strcmp(layout, xkb_rules->layout.name[i]) == 0) {
+ XtSetArg(args[0], XtNlabel, xkb_rules->layout.desc[i]);
+ XtSetValues(layoutb, args, 1);
+ break;
+ }
+
+ if (variant)
+ for (i = 0; i < xkb_rules->variant.nelem; i++)
+ if (strcmp(variant, xkb_rules->variant.name[i]) == 0) {
+ XtSetArg(args[0], XtNlabel, xkb_rules->variant.desc[i]);
+ XtSetValues(variantb, args, 1);
+ break;
+ }
+
+ if (options) {
+ XtSetArg(args[0], XtNlabel, options);
+ XtSetValues(optionsb, args, 1);
+ }
+
+ XtChangeManagedSet(&current, 1, NULL, NULL, &kbdml, 1);
+ current = kbdml;
+}
diff --git a/hw/xfree86/utils/xorgcfg/keyboard-cfg.h b/hw/xfree86/utils/xorgcfg/keyboard-cfg.h
new file mode 100644
index 000000000..6ff63c002
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/keyboard-cfg.h
@@ -0,0 +1,74 @@
+/*
+ * 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/keyboard-cfg.h,v 1.3 2001/03/02 22:39:27 paulo Exp $
+ */
+
+#include "config.h"
+#include <X11/extensions/XKBconfig.h>
+
+#ifndef _xf86cfg_keyboard_h
+#define _xf86cfg_keyboard_h
+
+/*
+ * All file names are from XProjectRoot or XWINHOME environment variable.
+ */
+#define XkbConfigDir "lib/X11/xkb/"
+#define XkbConfigFile "X0-config.keyboard"
+
+/*
+ * Types
+ */
+typedef struct {
+ char **name;
+ char **desc;
+ int nelem;
+} XF86XkbDescInfo;
+
+typedef struct {
+ XF86ConfInputPtr conf;
+ XkbDescPtr xkb;
+ XkbRF_VarDefsRec defs;
+ XkbConfigRtrnRec config;
+} XkbInfo;
+
+/*
+ * Prototypes
+ */
+XtPointer KeyboardConfig(XtPointer);
+void KeyboardModelAndLayout(XF86SetupInfo*);
+void InitializeKeyboard(void);
+Bool UpdateKeyboard(Bool);
+Bool WriteXKBConfiguration(char*, XkbConfigRtrnPtr);
+
+/*
+ * Initialization
+ */
+extern XkbInfo *xkb_info;
+
+#endif /* _xf86cfg_keyboard_h */
diff --git a/hw/xfree86/utils/xorgcfg/keyboard.xbm b/hw/xfree86/utils/xorgcfg/keyboard.xbm
new file mode 100644
index 000000000..69d4aac42
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/keyboard.xbm
@@ -0,0 +1,59 @@
+/*
+ * 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/keyboard.xbm,v 1.1 2000/04/04 22:36:59 dawes Exp $
+ */
+#define keyboard_width 50
+#define keyboard_height 44
+static unsigned char keyboard_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0xe0, 0xff, 0xff, 0xff,
+ 0xff, 0x1f, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x78, 0x9e,
+ 0xe7, 0x3d, 0xef, 0x79, 0x00, 0x18, 0x9a, 0xa6, 0x35, 0xad, 0x61, 0x00,
+ 0x18, 0x9e, 0xe7, 0x3d, 0xef, 0x61, 0x00, 0x18, 0x9e, 0xe7, 0x3d, 0xef,
+ 0x61, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0x00, 0x98, 0xf7, 0xde, 0x7b, 0xef, 0x67, 0x00, 0x98,
+ 0xd6, 0x5a, 0x6b, 0x2d, 0x66, 0x00, 0x98, 0xf7, 0xde, 0x7b, 0xef, 0x66,
+ 0x00, 0x98, 0xf7, 0xde, 0x7b, 0xef, 0x66, 0x00, 0x18, 0x00, 0x00, 0x00,
+ 0x80, 0x66, 0x00, 0x98, 0xdf, 0x7b, 0xef, 0xbd, 0x66, 0x00, 0x98, 0x58,
+ 0x6b, 0xad, 0xb5, 0x66, 0x00, 0x98, 0xdf, 0x7b, 0xef, 0xbd, 0x67, 0x00,
+ 0x98, 0xdf, 0x7b, 0xef, 0xbd, 0x67, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x60, 0x00, 0x98, 0xf7, 0xde, 0x7b, 0xef, 0x67, 0x00, 0x98, 0xd6, 0x5a,
+ 0x6b, 0x2d, 0x66, 0x00, 0x98, 0xf7, 0xde, 0x7b, 0xef, 0x67, 0x00, 0x98,
+ 0xf7, 0xde, 0x7b, 0xef, 0x67, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x60,
+ 0x00, 0x98, 0xf7, 0xfd, 0xf7, 0xbd, 0x67, 0x00, 0x98, 0x96, 0x05, 0x96,
+ 0xb5, 0x66, 0x00, 0x98, 0xf7, 0xfd, 0xf7, 0xbd, 0x67, 0x00, 0x98, 0xf7,
+ 0xfd, 0xf7, 0xbd, 0x67, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
+ 0x38, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff,
+ 0x3f, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
diff --git a/hw/xfree86/utils/xorgcfg/keyboard.xpm b/hw/xfree86/utils/xorgcfg/keyboard.xpm
new file mode 100644
index 000000000..5ef7b605d
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/keyboard.xpm
@@ -0,0 +1,66 @@
+/* XPM */
+/*
+ * 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/keyboard.xpm,v 1.1 2000/04/04 22:36:59 dawes Exp $
+ */
+static char * card_xpm[] = {
+"60 28 5 1",
+" c none",
+". c #AEBAAEBAAEBA",
+"X c #CF3CCF3CCF3C",
+"o c #8E388A288E38",
+"O c #69A671C669A6",
+" ........................ ",
+" .............................XXXXXXXXXXXXXXXXXXXXXXXX..... ",
+".XXXXXXXXXXXXXXXXXXXXXXXXXXXXX........................XXXXoO",
+".X........................................................oO",
+".X........................................................oO",
+".X.Xo..Xo.Xo.Xo..Xo.Xo.Xo.Xo.Xo.Xo..Xo.Xo.Xo..ooooooooooo.oO",
+".X.oo..oo.oo.oo..oo.oo.oo.oo.oo.oo..oo.oo.oo..XXXXXXXXXXX.oO",
+".X........................................................oO",
+".X........................................................oO",
+".X.Xo.Xo.Xo.Xo.Xo.Xo.Xo.Xo.Xo.Xo.o..Xo.Xo.Xo..Xo.Xo.Xo.Xo.oO",
+".X.oo.oo.oo.oo.oo.oo.oo.oo.oo.oo.o..oo.oo.oo..oo.oo.oo.oo.oO",
+".X........................................................oO",
+".X.XXo.Xo.Xo.Xo.Xo.Xo.Xo.Xo.Xo.oXo..Xo.Xo.Xo..Xo.Xo.Xo.Xo.oO",
+".X.ooo.oo.oo.oo.oo.oo.oo.oo.oo..Xo..oo.oo.oo..oo.oo.oo.Xo.oO",
+".X..............................Xo.....................Xo.oO",
+".X.Xo.Xo.Xo.Xo.Xo.Xo.Xo.Xo.Xo.XXXo..Xo.Xo.Xo..Xo.Xo.Xo.Xo.oO",
+".X.oo.oo.oo.oo.oo.oo.oo.oo.oo.oooo..oo.oo.oo..oo.oo.oo.oo.oO",
+".X........................................................oO",
+".X.XXo.Xo.Xo.Xo.Xo.Xo.Xo.Xo.Xo.XXo.....Xo.....Xo.Xo.Xo.Xo.oO",
+".X.ooo.oo.oo.oo.oo.oo.oo.oo.oo.ooo.....oo.....oo.oo.oo.Xo.oO",
+".X.....................................................Xo.oO",
+".X.Xo.Xo.Xo.XXXXXXXXXXXXo.Xo.Xo.Xo..Xo.Xo.Xo..XXXXo.Xo.Xo.oO",
+".X.oo.oo.oo.ooooooooooooo.oo.oo.oo..oo.oo.oo..ooooo.oo.oo.oO",
+".X........................................................oO",
+".X........................................................oO",
+".Xooooo.......................oooooooooooooooooooooooooooooO",
+" XOOOOOoooooooooooooooooooooooOOOOOOOOOOOOOOOOOOOOOOOOOOOOO ",
+" OOOOOOOOOOOOOOOOOOOOOOO "};
diff --git a/hw/xfree86/utils/xorgcfg/left.xbm b/hw/xfree86/utils/xorgcfg/left.xbm
new file mode 100644
index 000000000..bfb8f3ba8
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/left.xbm
@@ -0,0 +1,8 @@
+#define left_width 19
+#define left_height 19
+static unsigned char left_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00,
+ 0x00, 0x07, 0x00, 0x80, 0x07, 0x00, 0xc0, 0x07, 0x00, 0xe0, 0xff, 0x01,
+ 0xf0, 0xff, 0x01, 0xf8, 0xff, 0x01, 0xf0, 0xff, 0x01, 0xe0, 0xff, 0x01,
+ 0xc0, 0x07, 0x00, 0x80, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x06, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/hw/xfree86/utils/xorgcfg/loader.c b/hw/xfree86/utils/xorgcfg/loader.c
new file mode 100644
index 000000000..ddfa2903f
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/loader.c
@@ -0,0 +1,396 @@
+/*
+ * 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/loader.c,v 1.19 2002/06/06 21:03:32 paulo Exp $
+ */
+
+#include "config.h"
+#include "cards.h"
+#include "options.h"
+#include "loader.h"
+#include "stubs.h"
+#include <X11/Xresource.h>
+
+#ifdef USE_MODULES
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <ctype.h>
+
+#include <stdarg.h>
+
+#ifndef SIGNALRETURNSINT
+void sig_handler(int);
+#else
+int sig_handler(int);
+#endif /* SIGNALRETURNSINT */
+
+static Bool EnumDatabase(XrmDatabase*, XrmBindingList, XrmQuarkList,
+ XrmRepresentation*, XrmValue*, XPointer);
+
+static sigjmp_buf jmp;
+int signal_caught;
+int error_level;
+char *loaderPath, **loaderList, **ploaderList;
+extern XrmDatabase options_xrm;
+extern int noverify;
+extern ModuleType module_type;
+static OptionInfoPtr option;
+
+extern FontModule *font_module;
+extern int numFontModules;
+
+char **checkerLegend;
+int *checkerErrors;
+
+#ifndef SIGNALRETURNSINT
+void
+#else
+int
+#endif
+sig_handler(int sig)
+{
+ char *str;
+
+ switch (sig) {
+ case SIGTRAP:
+ str = "TRAP";
+ break;
+ case SIGBUS:
+ str = "BUS";
+ break;
+ case SIGSEGV:
+ str = "SEGV";
+ break;
+ case SIGILL:
+ str = "ILL";
+ break;
+ case SIGFPE:
+ str = "FPE";
+ break;
+ default:
+ str = "???";
+ break;
+ }
+
+ if (signal_caught == 1) {
+ ErrorF(" ERROR I am dead.\n");
+ exit(1);
+ }
+ else if (signal_caught == 2)
+ abort();
+ ++signal_caught;
+ ErrorF(" ERROR SIG%s caught!\n", str);
+ if (!noverify)
+ error_level += 50;
+ siglongjmp(jmp, 1);
+ /*NOTREACHED*/
+}
+
+void
+CheckMsg(int code, char *fmt, ...)
+{
+ va_list ap;
+
+ ++checkerErrors[code];
+ ErrorF("%3d ", code);
+
+ va_start(ap, fmt);
+ VErrorF(fmt, ap);
+ va_end(ap);
+}
+
+static Bool
+EnumDatabase(XrmDatabase *db, XrmBindingList bindings, XrmQuarkList quarks,
+ XrmRepresentation *type, XrmValue *value, XPointer closure)
+{
+ char *res = XrmQuarkToString(quarks[1]);
+
+ if (res) {
+ option = module_options->option;
+ while (option->name) {
+ if (strcasecmp(option->name, res) == 0)
+ return (False);
+ ++option;
+ }
+ CheckMsg(CHECKER_OPTION_UNUSED,
+ "WARNING %s.%s is not used\n",
+ XrmQuarkToString(quarks[0]), res);
+ ++error_level;
+ }
+
+ return (False);
+}
+
+Bool
+LoaderInitializeOptions(void)
+{
+ static int first = 1;
+ static char *modules = "lib/modules";
+ volatile Bool options_ok = False;
+ char *ptr, query[256];
+ char *ptr2, query2[256];
+ char *type;
+ XrmValue value;
+ XrmQuark names[2];
+ XrmQuark classes[2];
+ volatile int i;
+ static ModuleType module_types[] = {
+ GenericModule, FontRendererModule, InputModule, VideoModule, NullModule
+ };
+
+ /* The offset in this vector must match loader.h:enum ModuleType values */
+ static char *module_strs[] = {
+ "Null Module", "Video Module", "Input Module", "Generic Module", "Font Module"
+ };
+
+ if (first) {
+ checkerLegend = (char**)
+ XtCalloc(1, sizeof(char*) * (CHECKER_LAST_MESSAGE + 1));
+ checkerErrors = (int*)
+ XtCalloc(1, sizeof(int) * (CHECKER_LAST_MESSAGE + 1));
+ xf86cfgLoaderInit();
+ first = 0;
+
+ checkerLegend[CHECKER_OPTIONS_FILE_MISSING] =
+ "The Options file, normally /usr/X11R6/lib/X11/Options was not found.\n"
+ "In the sources, it is at xc/programs/Xserver/hw/xfree86/Options.";
+ checkerLegend[CHECKER_OPTION_DESCRIPTION_MISSING] =
+ "No description for the module option. The description should be in\n"
+ "in the Options file, and using the sintax:\n"
+ "Module.Option: any text describing the option";
+ checkerLegend[CHECKER_LOAD_FAILED] =
+ "Failed to load the module. Usually the loader will print a complete\n"
+ "description for the reason the module was not loaded. Use the -verbose\n"
+ "command line option if it is not printing any messages.";
+ checkerLegend[CHECKER_RECOGNIZED_AS] =
+ "This message means the module code did not follow what was expected\n"
+ "by the checker. For video drivers, it did not call xf86AddDriver,\n"
+ "a input module did not call xf86AddInputDriver and a font renderer\n"
+ "module did not call LoadFont. This message can also be printed if\n"
+ "the module is in the incorrect directory.";
+ checkerLegend[CHECKER_NO_OPTIONS_AVAILABLE] =
+ "The driver does not have an AvailableOptions function, or that\n"
+ "function is returning NULL. If the driver is returning NULL, and\n"
+ "really does not need any options from XF86Config, than the message\n"
+ "can be ignored.";
+ checkerLegend[CHECKER_NO_VENDOR_CHIPSET] =
+ "The checker could not fetch the PCI chipset/vendor information from\n"
+ "the module. The checker currently wraps xf86PrintChipsets and\n"
+ "xf86MatchPciInstances to read the information from the module.";
+ checkerLegend[CHECKER_CANNOT_VERIFY_CHIPSET] =
+ "The vendor id was not found, so it is not possible to search the list\n"
+ "of chipsets.";
+ checkerLegend[CHECKER_OPTION_UNUSED] =
+ "The option description is defined in the Options file, but the option\n"
+ "was name not retrieved when calling the module AvailableOptions.";
+ checkerLegend[CHECKER_NOMATCH_CHIPSET_STRINGS] =
+ "The string specified in the module does not match the one in\n"
+ "common/xf86PciInfo.h";
+ checkerLegend[CHECKER_CHIPSET_NOT_LISTED] =
+ "This means that common/xf86PciInfo.h does not have an entry for the\n"
+ "given vendor and id.";
+ checkerLegend[CHECKER_CHIPSET_NOT_SUPPORTED] =
+ "The chipset is listed in common/xf86PciInfo.h, but the driver does\n"
+ "not support it, or does not list it in the chipsets fetched by the checker.";
+ checkerLegend[CHECKER_CHIPSET_NO_VENDOR] =
+ "The vendor id specified to xf86MatchPciInstances is not defined in\n"
+ "common/xf86PciInfo.h";
+ checkerLegend[CHECKER_NO_CHIPSETS] =
+ "No chipsets were passed to xf86MatchPciIntances.";
+ checkerLegend[CHECKER_FILE_MODULE_NAME_MISMATCH] =
+ "The module name string does not match the the modname field of the\n"
+ "XF86ModuleVersionInfo structure. This generally is not an error, but\n"
+ "to may be a good idea to use the same string to avoid confusion.";
+ }
+
+ if (XF86Module_path == NULL) {
+ XF86Module_path = malloc(strlen(XFree86Dir) + strlen(modules) + 2);
+ sprintf(XF86Module_path, "%s/%s", XFree86Dir, modules);
+ }
+
+ if (loaderPath == NULL || strcmp(XF86Module_path, loaderPath))
+ loaderPath = strdup(XF86Module_path);
+ else
+ /* nothing new */
+ return (True);
+
+ if (!noverify) {
+ options_ok = InitializeOptionsDatabase();
+ InitializePciInfo();
+ }
+
+ for (i = 0; module_types[i] != NullModule; i++) {
+ xf86cfgLoaderInitList(module_types[i]);
+ if (!noverify)
+ ErrorF("================= Checking modules of type \"%s\" =================\n",
+ module_strs[module_types[i]]);
+
+ if (loaderList) {
+ for (ploaderList = loaderList; *ploaderList; ploaderList++) {
+ signal_caught = 0;
+ signal(SIGTRAP, sig_handler);
+ signal(SIGBUS, sig_handler);
+ signal(SIGSEGV, sig_handler);
+ signal(SIGILL, sig_handler);
+ signal(SIGFPE, sig_handler);
+ if (sigsetjmp(jmp, 1) == 0) {
+ if (!noverify) {
+ int ok, nfont_modules;
+
+ nfont_modules = numFontModules;
+ error_level = 0;
+ ErrorF("CHECK MODULE %s\n", *ploaderList);
+ if ((ok = xf86cfgCheckModule()) == 0) {
+ CheckMsg(CHECKER_LOAD_FAILED,
+ "ERROR Failed to load module.\n");
+ error_level += 50;
+ }
+ else if (module_type != module_types[i]) {
+ CheckMsg(CHECKER_RECOGNIZED_AS,
+ "WARNING %s recognized as a \"%s\"\n", *ploaderList,
+ module_strs[module_type]);
+ ++error_level;
+ }
+ if (ok) {
+ if (options_ok) {
+ if ((module_options == NULL || module_options->option == NULL) &&
+ module_type != GenericModule) {
+ CheckMsg(CHECKER_NO_OPTIONS_AVAILABLE,
+ "WARNING Not a generic module, but no options available.\n");
+ ++error_level;
+ }
+ else if (module_options && strcmp(module_options->name, *ploaderList) == 0) {
+ ErrorF(" CHECK OPTIONS\n");
+ option = module_options->option;
+
+ while (option->name) {
+ XmuSnprintf(query, sizeof(query), "%s.%s", *ploaderList, option->name);
+ for (ptr = query, ptr2 = query2; *ptr; ptr++) {
+ if (*ptr != '_' && *ptr != ' ' && *ptr != '\t')
+ *ptr2 = tolower(*ptr);
+ }
+ *ptr2 = '\0';
+ /* all resources are in lowercase */
+ if (!XrmGetResource(options_xrm, query2, "Module.Option", &type, &value) ||
+ value.addr == NULL) {
+ CheckMsg(CHECKER_OPTION_DESCRIPTION_MISSING,
+ "WARNING no description for %s\n", query);
+ ++error_level;
+ }
+ ++option;
+ }
+
+ /* now do a linear search for Options file entries that are not
+ * in the driver.
+ */
+ names[0] = XrmPermStringToQuark(module_options->name);
+ classes[0] = XrmPermStringToQuark("Option");
+ names[1] = classes[1] = NULLQUARK;
+ (void)XrmEnumerateDatabase(options_xrm, (XrmNameList)&names, (XrmClassList)&classes,
+ XrmEnumOneLevel, EnumDatabase, NULL);
+ }
+ }
+ else {
+ CheckMsg(CHECKER_OPTIONS_FILE_MISSING,
+ "ERROR Options file missing.\n");
+ error_level += 10;
+ }
+
+ if (module_type == VideoModule &&
+ (module_options == NULL || module_options->vendor < 0 ||
+ module_options->chipsets == NULL)) {
+ CheckMsg(CHECKER_NO_VENDOR_CHIPSET,
+ "WARNING No vendor/chipset information available.\n");
+ ++error_level;
+ }
+ else if (module_type == VideoModule) {
+ if (module_options == NULL) {
+ /* No description for this, if this happen,
+ * something really strange happened. */
+ ErrorF(" ERROR No module_options!?!\n");
+ error_level += 50;
+ }
+ else {
+ ErrorF(" CHECK CHIPSETS\n");
+ CheckChipsets(module_options, &error_level);
+ }
+ }
+
+ /* font modules check */
+ if (module_type == FontRendererModule) {
+ if (strcmp(*ploaderList, font_module->name)) {
+ /* not an error */
+ ErrorF(" NOTICE FontModule->name specification mismatch: \"%s\" \"%s\"\n",
+ *ploaderList, font_module->name);
+ }
+ if (nfont_modules + 1 != numFontModules) {
+ /* not an error */
+ ErrorF(" NOTICE font module \"%s\" loaded more than one font renderer.\n",
+ *ploaderList);
+ }
+ }
+ else if (nfont_modules != numFontModules) {
+ ErrorF(" WARNING number of font modules changed from %d to %d.\n",
+ nfont_modules, numFontModules);
+ ++error_level;
+ }
+ }
+ ErrorF(" SUMMARY error_level set to %d.\n\n", error_level);
+ }
+ else
+ (void)xf86cfgCheckModule();
+ }
+ signal(SIGTRAP, SIG_DFL);
+ signal(SIGBUS, SIG_DFL);
+ signal(SIGSEGV, SIG_DFL);
+ signal(SIGILL, SIG_DFL);
+ signal(SIGFPE, SIG_DFL);
+ }
+ xf86cfgLoaderFreeList();
+ }
+ else
+ ErrorF(" ERROR Failed to initialize module list.\n");
+ }
+
+ if (!noverify) {
+ ErrorF("===================================== LEGEND ===============================\n");
+ ErrorF("NOTICE lines are just informative.\n");
+ ErrorF("WARNING lines add 1 to error_level.\n");
+ ErrorF("ERROR lines add 2 or more (based on the severity of the error) to error_level.\n\n");
+ for (i = 0; i <= CHECKER_LAST_MESSAGE; i++)
+ if (checkerErrors[i]) {
+ ErrorF("%3d\n%s\n\n", i, checkerLegend[i]);
+ }
+ }
+
+ return (True);
+}
+#endif
diff --git a/hw/xfree86/utils/xorgcfg/loader.h b/hw/xfree86/utils/xorgcfg/loader.h
new file mode 100644
index 000000000..f3f8490bc
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/loader.h
@@ -0,0 +1,171 @@
+/*
+ * 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/loader.h,v 1.7 2001/07/09 23:45:24 paulo Exp $
+ */
+
+#ifdef USE_MODULES
+#ifndef LOADER_PRIVATE
+#include "config.h"
+#include "stubs.h"
+
+#else
+
+#define XFree86LOADER /* not really */
+#define IN_LOADER
+
+#include "xf86.h"
+#include "xf86str.h"
+#include "xf86Opt.h"
+#include "xf86Module.h"
+
+#define XINPUT
+#include "xf86Xinput.h"
+
+#include "fontmod.h"
+#include "loaderProcs.h"
+
+#include <sym.h>
+#include <xf86_ansic.h>
+
+void LoaderDefaultFunc(void);
+#endif
+
+#ifndef _xf86cfg_loader_h
+#define _xf86cfg_loader_h
+
+void xf86cfgLoaderInit(void);
+void xf86cfgLoaderInitList(int);
+void xf86cfgLoaderFreeList(void);
+int xf86cfgCheckModule(void);
+
+#ifndef LOADER_PRIVATE
+/* common/xf86Opt.h */
+typedef struct {
+ double freq;
+ int units;
+} OptFrequency;
+
+typedef union {
+ unsigned long num;
+ char * str;
+ double realnum;
+ Bool bool;
+ OptFrequency freq;
+} ValueUnion;
+
+typedef enum {
+ OPTV_NONE = 0,
+ OPTV_INTEGER,
+ OPTV_STRING, /* a non-empty string */
+ OPTV_ANYSTR, /* Any string, including an empty one */
+ OPTV_REAL,
+ OPTV_BOOLEAN,
+ OPTV_FREQ
+} OptionValueType;
+
+typedef enum {
+ OPTUNITS_HZ = 1,
+ OPTUNITS_KHZ,
+ OPTUNITS_MHZ
+} OptFreqUnits;
+
+typedef struct {
+ int token;
+ const char* name;
+ OptionValueType type;
+ ValueUnion value;
+ Bool found;
+} OptionInfoRec, *OptionInfoPtr;
+
+/* fontmod.h */
+typedef void (*InitFont)(void);
+
+typedef struct {
+ InitFont initFunc;
+ char * name;
+ void *module;
+} FontModule;
+
+extern FontModule *FontModuleList;
+
+typedef struct {
+ int token; /* id of the token */
+ const char * name; /* token name */
+} SymTabRec, *SymTabPtr;
+#endif /* !LOADER_PRIVATE */
+
+typedef enum {
+ NullModule = 0,
+ VideoModule,
+ InputModule,
+ GenericModule,
+ FontRendererModule
+} ModuleType;
+
+typedef struct _xf86cfgModuleOptions {
+ char *name;
+ ModuleType type;
+ OptionInfoPtr option;
+ int vendor;
+ SymTabPtr chipsets;
+ struct _xf86cfgModuleOptions *next;
+} xf86cfgModuleOptions;
+
+extern xf86cfgModuleOptions *module_options;
+
+/* When adding a new code to the LEGEND, also update checkerLegend
+ * in loader.c
+ */
+extern char **checkerLegend;
+extern int *checkerErrors;
+#define CHECKER_OPTIONS_FILE_MISSING 1
+#define CHECKER_OPTION_DESCRIPTION_MISSING 2
+#define CHECKER_LOAD_FAILED 3
+#define CHECKER_RECOGNIZED_AS 4
+#define CHECKER_NO_OPTIONS_AVAILABLE 5
+#define CHECKER_NO_VENDOR_CHIPSET 6
+#define CHECKER_CANNOT_VERIFY_CHIPSET 7
+#define CHECKER_OPTION_UNUSED 8
+#define CHECKER_NOMATCH_CHIPSET_STRINGS 9
+#define CHECKER_CHIPSET_NOT_LISTED 10
+#define CHECKER_CHIPSET_NOT_SUPPORTED 11
+#define CHECKER_CHIPSET_NO_VENDOR 12
+#define CHECKER_NO_CHIPSETS 13
+#define CHECKER_FILE_MODULE_NAME_MISMATCH 14
+
+#define CHECKER_LAST_MESSAGE 14
+
+extern void CheckMsg(int, char*, ...);
+
+#ifndef LOADER_PRIVATE
+int LoaderInitializeOptions(void);
+#endif
+#endif /* USE_MODULES */
+
+#endif /* _xf86cfg_loader_h */
diff --git a/hw/xfree86/utils/xorgcfg/loadmod.c b/hw/xfree86/utils/xorgcfg/loadmod.c
new file mode 100644
index 000000000..a53bffa01
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/loadmod.c
@@ -0,0 +1,658 @@
+/*
+ * 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/loadmod.c,v 1.14.2.1 2003/03/13 04:10:50 tsi Exp $
+ */
+
+#ifdef USE_MODULES
+#include <setjmp.h>
+
+#ifndef HAS_GLIBC_SIGSETJMP
+#if defined(setjmp) && defined(__GNU_LIBRARY__) && \
+ (!defined(__GLIBC__) || (__GLIBC__ < 2) || \
+ ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 3)))
+#define HAS_GLIBC_SIGSETJMP 1
+#endif
+#endif
+
+#define LOADER_PRIVATE
+#include "loader.h"
+
+#define True 1
+#define False 0
+#define XtPointer char*
+#define XtMalloc malloc
+#define XtCalloc calloc
+#define XtRealloc realloc
+#define XtFree free
+#define XtNew(t) malloc(sizeof(t))
+#define XtNewString(s) ((s) ? strdup(s) : NULL)
+
+#define pointer void*
+
+/* XXX beware (or fix it) libc functions called here are the xf86 ones */
+
+static void AddModuleOptions(char*, const OptionInfoRec*);
+#if 0
+void xf86AddDriver(DriverPtr, void*, int);
+Bool xf86ServerIsOnlyDetecting(void);
+void xf86AddInputDriver(InputDriverPtr, pointer, int);
+void xf86AddModuleInfo(ModuleInfoPtr, void*);
+Bool xf86LoaderCheckSymbol(const char*);
+void xf86LoaderRefSymLists(const char **, ...);
+void xf86LoaderReqSymLists(const char **, ...);
+void xf86Msg(int, const char*, ...);
+void xf86PrintChipsets(const char*, const char*, SymTabPtr);
+void xf86ErrorFVerb(int verb, const char *format, ...);
+pciVideoPtr *xf86GetPciVideoInfo(void);
+int xf86MatchDevice(const char*, GDevPtr**);
+int xf86MatchPciInstances(const char*, int, SymTabPtr, PciChipsets*, GDevPtr*, int, DriverPtr,int**);
+int xf86MatchIsaInstances(const char*, SymTabPtr, pointer*, DriverPtr, pointer, GDevPtr*, int, int**);
+void *xf86LoadDrvSubModule(DriverPtr drv, const char*);
+void xf86DrvMsg(int, int, const char*, ...);
+pciConfigPtr *xf86GetPciConfigInfo(void);
+Bool xf86IsPrimaryPci(pcVideoPtr*);
+#endif
+
+extern char *loaderPath, **loaderList, **ploaderList;
+xf86cfgModuleOptions *module_options;
+FontModule *font_module;
+int numFontModules;
+
+extern int noverify, error_level;
+
+int xf86ShowUnresolved = 1;
+
+LOOKUP miLookupTab[] = {{0,0}};
+LOOKUP dixLookupTab[] = {{0,0}};
+LOOKUP fontLookupTab[] = {{0,0}};
+LOOKUP extLookupTab[] = {{0,0}};
+LOOKUP xfree86LookupTab[] = {
+ /* Loader functions */
+ SYMFUNC(LoaderDefaultFunc)
+ SYMFUNC(LoadSubModule)
+ SYMFUNC(DuplicateModule)
+ SYMFUNC(LoaderErrorMsg)
+ SYMFUNC(LoaderCheckUnresolved)
+ SYMFUNC(LoadExtension)
+ SYMFUNC(LoadFont)
+ SYMFUNC(LoaderReqSymbols)
+ SYMFUNC(LoaderReqSymLists)
+ SYMFUNC(LoaderRefSymbols)
+ SYMFUNC(LoaderRefSymLists)
+ SYMFUNC(UnloadSubModule)
+ SYMFUNC(LoaderSymbol)
+ SYMFUNC(LoaderListDirs)
+ SYMFUNC(LoaderFreeDirList)
+ SYMFUNC(LoaderGetOS)
+
+ /*
+ * these here are our own interfaces to libc functions
+ */
+ SYMFUNC(xf86abort)
+ SYMFUNC(xf86abs)
+ SYMFUNC(xf86acos)
+ SYMFUNC(xf86asin)
+ SYMFUNC(xf86atan)
+ SYMFUNC(xf86atan2)
+ SYMFUNC(xf86atof)
+ SYMFUNC(xf86atoi)
+ SYMFUNC(xf86atol)
+ SYMFUNC(xf86bsearch)
+ SYMFUNC(xf86ceil)
+ SYMFUNC(xf86calloc)
+ SYMFUNC(xf86clearerr)
+ SYMFUNC(xf86close)
+ SYMFUNC(xf86cos)
+ SYMFUNC(xf86exit)
+ SYMFUNC(xf86exp)
+ SYMFUNC(xf86fabs)
+ SYMFUNC(xf86fclose)
+ SYMFUNC(xf86feof)
+ SYMFUNC(xf86ferror)
+ SYMFUNC(xf86fflush)
+ SYMFUNC(xf86fgetc)
+ SYMFUNC(xf86fgetpos)
+ SYMFUNC(xf86fgets)
+ SYMFUNC(xf86finite)
+ SYMFUNC(xf86floor)
+ SYMFUNC(xf86fmod)
+ SYMFUNC(xf86fopen)
+ SYMFUNC(xf86fprintf)
+ SYMFUNC(xf86fputc)
+ SYMFUNC(xf86fputs)
+ SYMFUNC(xf86fread)
+ SYMFUNC(xf86free)
+ SYMFUNC(xf86freopen)
+ SYMFUNC(xf86frexp)
+ SYMFUNC(xf86fscanf)
+ SYMFUNC(xf86fseek)
+ SYMFUNC(xf86fsetpos)
+ SYMFUNC(xf86ftell)
+ SYMFUNC(xf86fwrite)
+ SYMFUNC(xf86getc)
+ SYMFUNC(xf86getenv)
+ SYMFUNC(xf86getpagesize)
+ SYMFUNC(xf86hypot)
+ SYMFUNC(xf86ioctl)
+ SYMFUNC(xf86isalnum)
+ SYMFUNC(xf86isalpha)
+ SYMFUNC(xf86iscntrl)
+ SYMFUNC(xf86isdigit)
+ SYMFUNC(xf86isgraph)
+ SYMFUNC(xf86islower)
+ SYMFUNC(xf86isprint)
+ SYMFUNC(xf86ispunct)
+ SYMFUNC(xf86isspace)
+ SYMFUNC(xf86isupper)
+ SYMFUNC(xf86isxdigit)
+ SYMFUNC(xf86labs)
+ SYMFUNC(xf86ldexp)
+ SYMFUNC(xf86log)
+ SYMFUNC(xf86log10)
+ SYMFUNC(xf86lseek)
+ SYMFUNC(xf86malloc)
+ SYMFUNC(xf86memchr)
+ SYMFUNC(xf86memcmp)
+ SYMFUNC(xf86memcpy)
+#if (defined(__powerpc__) && (defined(Lynx) || defined(linux))) || defined(__sparc__) || defined(__ia64__) || defined (__x86_64__)
+ /*
+ * Some PPC, SPARC, and IA64 compilers generate calls to memcpy to handle
+ * structure copies. This causes a problem both here and in shared
+ * libraries as there is no way to map the name of the call to the
+ * correct function.
+ */
+ SYMFUNC(memcpy)
+ /*
+ * Some PPC, SPARC, and IA64 compilers generate calls to memset to handle
+ * aggregate initializations.
+ */
+ SYMFUNC(memset)
+#endif
+ SYMFUNC(xf86memmove)
+ SYMFUNC(xf86memset)
+ SYMFUNC(xf86mmap)
+ SYMFUNC(xf86modf)
+ SYMFUNC(xf86munmap)
+ SYMFUNC(xf86open)
+ SYMFUNC(xf86perror)
+ SYMFUNC(xf86pow)
+ SYMFUNC(xf86printf)
+ SYMFUNC(xf86qsort)
+ SYMFUNC(xf86read)
+ SYMFUNC(xf86realloc)
+ SYMFUNC(xf86remove)
+ SYMFUNC(xf86rename)
+ SYMFUNC(xf86rewind)
+ SYMFUNC(xf86setbuf)
+ SYMFUNC(xf86setvbuf)
+ SYMFUNC(xf86sin)
+ SYMFUNC(xf86snprintf)
+ SYMFUNC(xf86sprintf)
+ SYMFUNC(xf86sqrt)
+ SYMFUNC(xf86sscanf)
+ SYMFUNC(xf86strcat)
+ SYMFUNC(xf86strcmp)
+ SYMFUNC(xf86strcasecmp)
+ SYMFUNC(xf86strcpy)
+ SYMFUNC(xf86strcspn)
+ SYMFUNC(xf86strerror)
+ SYMFUNC(xf86strlen)
+ SYMFUNC(xf86strncmp)
+ SYMFUNC(xf86strncasecmp)
+ SYMFUNC(xf86strncpy)
+ SYMFUNC(xf86strpbrk)
+ SYMFUNC(xf86strchr)
+ SYMFUNC(xf86strrchr)
+ SYMFUNC(xf86strspn)
+ SYMFUNC(xf86strstr)
+ SYMFUNC(xf86strtod)
+ SYMFUNC(xf86strtok)
+ SYMFUNC(xf86strtol)
+ SYMFUNC(xf86strtoul)
+ SYMFUNC(xf86tan)
+ SYMFUNC(xf86tmpfile)
+ SYMFUNC(xf86tolower)
+ SYMFUNC(xf86toupper)
+ SYMFUNC(xf86ungetc)
+ SYMFUNC(xf86vfprintf)
+ SYMFUNC(xf86vsnprintf)
+ SYMFUNC(xf86vsprintf)
+ SYMFUNC(xf86write)
+
+/* non-ANSI C functions */
+ SYMFUNC(xf86opendir)
+ SYMFUNC(xf86closedir)
+ SYMFUNC(xf86readdir)
+ SYMFUNC(xf86rewinddir)
+ SYMFUNC(xf86ffs)
+ SYMFUNC(xf86strdup)
+ SYMFUNC(xf86bzero)
+ SYMFUNC(xf86usleep)
+ SYMFUNC(xf86execl)
+
+ SYMFUNC(xf86getsecs)
+ SYMFUNC(xf86fpossize) /* for returning sizeof(fpos_t) */
+
+ SYMFUNC(xf86stat)
+ SYMFUNC(xf86fstat)
+ SYMFUNC(xf86access)
+ SYMFUNC(xf86geteuid)
+ SYMFUNC(xf86getegid)
+ SYMFUNC(xf86getpid)
+ SYMFUNC(xf86mknod)
+ SYMFUNC(xf86chmod)
+ SYMFUNC(xf86chown)
+ SYMFUNC(xf86sleep)
+ SYMFUNC(xf86mkdir)
+ SYMFUNC(xf86shmget)
+ SYMFUNC(xf86shmat)
+ SYMFUNC(xf86shmdt)
+ SYMFUNC(xf86shmctl)
+#ifdef HAS_GLIBC_SIGSETJMP
+ SYMFUNC(xf86setjmp)
+ SYMFUNC(xf86setjmp0)
+#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+ SYMFUNCALIAS("xf86setjmp1",__sigsetjmp)
+#else
+ SYMFUNC(xf86setjmp1)
+#endif
+#else
+ SYMFUNCALIAS("xf86setjmp",setjmp)
+ SYMFUNCALIAS("xf86setjmp0",setjmp)
+ SYMFUNC(xf86setjmp1)
+#endif
+ SYMFUNCALIAS("xf86longjmp",longjmp)
+ SYMFUNC(xf86getjmptype)
+ SYMFUNC(xf86setjmp1_arg2)
+ SYMFUNC(xf86setjmperror)
+
+ SYMFUNC(xf86AddDriver)
+ SYMFUNC(xf86ServerIsOnlyDetecting)
+ SYMFUNC(xf86AddInputDriver)
+ SYMFUNC(xf86AddModuleInfo)
+ SYMFUNC(xf86LoaderCheckSymbol)
+
+ SYMFUNC(xf86LoaderRefSymLists)
+ SYMFUNC(xf86LoaderReqSymLists)
+ SYMFUNC(xf86Msg)
+ SYMFUNC(ErrorF)
+ SYMFUNC(xf86PrintChipsets)
+ SYMFUNC(xf86ErrorFVerb)
+ SYMFUNC(xf86GetPciVideoInfo)
+ SYMFUNC(xf86MatchDevice)
+ SYMFUNC(xf86MatchPciInstances)
+ SYMFUNC(xf86MatchIsaInstances)
+ SYMFUNC(Xfree)
+ SYMFUNC(xf86LoadDrvSubModule)
+ SYMFUNC(xf86DrvMsg)
+ SYMFUNC(xf86GetPciConfigInfo)
+ SYMFUNC(xf86IsPrimaryPci)
+ {0,0}
+};
+
+static DriverPtr driver;
+static ModuleInfoPtr info;
+static SymTabPtr chips;
+static int vendor;
+ModuleType module_type = GenericModule;
+
+static void
+AddModuleOptions(char *name, const OptionInfoRec *option)
+{
+ xf86cfgModuleOptions *ptr;
+ const OptionInfoRec *tmp;
+ SymTabPtr ctmp;
+ int count;
+
+ /* XXX If the module is already in the list, then it means that
+ * it is now being properly loaded by xf86cfg and the "fake" entry
+ * added in xf86cfgLoaderInitList() isn't required anymore.
+ * Currently:
+ * ati and vmware are known to fail. */
+ for (ptr = module_options; ptr; ptr = ptr->next)
+ if (strcmp(name, ptr->name) == 0) {
+ fprintf(stderr, "Module %s already in list!\n", name);
+ return;
+ }
+
+ ptr = XtNew(xf86cfgModuleOptions);
+ ptr->name = XtNewString(name);
+ ptr->type = module_type;
+ if (option) {
+ for (count = 0, tmp = option; tmp->name != NULL; tmp++, count++)
+ ;
+ ++count;
+ ptr->option = XtCalloc(1, count * sizeof(OptionInfoRec));
+ for (count = 0, tmp = option; tmp->name != NULL; count++, tmp++) {
+ memcpy(&ptr->option[count], tmp, sizeof(OptionInfoRec));
+ ptr->option[count].name = XtNewString(tmp->name);
+ if (tmp->type == OPTV_STRING || tmp->type == OPTV_ANYSTR)
+ ptr->option[count].value.str = XtNewString(tmp->value.str);
+ }
+ }
+ else
+ ptr->option = NULL;
+ if (vendor != -1 && chips) {
+ ptr->vendor = vendor;
+ for (count = 0, ctmp = chips; ctmp->name; ctmp++, count++)
+ ;
+ ++count;
+ ptr->chipsets = XtCalloc(1, count * sizeof(SymTabRec));
+ for (count = 0, ctmp = chips; ctmp->name != NULL; count++, ctmp++) {
+ memcpy(&ptr->chipsets[count], ctmp, sizeof(SymTabRec));
+ ptr->chipsets[count].name = XtNewString(ctmp->name);
+ }
+ }
+ else
+ ptr->chipsets = NULL;
+
+ ptr->next = module_options;
+ module_options = ptr;
+}
+
+extern void xf86WrapperInit(void);
+
+void
+xf86cfgLoaderInit(void)
+{
+ LoaderInit();
+ xf86WrapperInit();
+}
+
+void
+xf86cfgLoaderInitList(int type)
+{
+ static const char *generic[] = {
+ ".",
+ NULL
+ };
+ static const char *video[] = {
+ "drivers",
+ NULL
+ };
+ static const char *input[] = {
+ "input",
+ NULL
+ };
+ static const char *font[] = {
+ "fonts",
+ NULL
+ };
+ const char **subdirs;
+
+ switch (type) {
+ case GenericModule:
+ subdirs = generic;
+ break;
+ case VideoModule:
+ subdirs = video;
+ break;
+ case InputModule:
+ subdirs = input;
+ break;
+ case FontRendererModule:
+ subdirs = font;
+ break;
+ default:
+ fprintf(stderr, "Invalid value passed to xf86cfgLoaderInitList.\n");
+ subdirs = generic;
+ break;
+ }
+ LoaderSetPath(loaderPath);
+ loaderList = LoaderListDirs(subdirs, NULL);
+
+ /* XXX Xf86cfg isn't able to provide enough wrapper functions
+ * to these drivers. Maybe the drivers could also be changed
+ * to work better when being loaded "just for testing" */
+ if (type == VideoModule) {
+ module_type = VideoModule;
+ AddModuleOptions("vmware", NULL);
+ AddModuleOptions("ati", NULL);
+ module_type = NullModule;
+ }
+}
+
+void
+xf86cfgLoaderFreeList(void)
+{
+ LoaderFreeDirList(loaderList);
+}
+
+int
+xf86cfgCheckModule(void)
+{
+ int errmaj, errmin;
+ ModuleDescPtr module;
+ int nfonts;
+ FontModule *fonts, *pfont_module;
+
+ driver = NULL;
+ chips = NULL;
+ info = NULL;
+ pfont_module = NULL;
+ vendor = -1;
+ module_type = GenericModule;
+
+ if ((module = LoadModule(*ploaderList, NULL, NULL, NULL, NULL,
+ NULL, &errmaj, &errmin)) == NULL) {
+ LoaderErrorMsg(NULL, *ploaderList, errmaj, errmin);
+ return (0);
+ }
+ else if (driver && driver->AvailableOptions) {
+ /* at least fbdev does not call xf86MatchPciInstances in Probe */
+ if (driver->Identify)
+ (*driver->Identify)(-1);
+ if (driver->Probe)
+ (*driver->Probe)(driver, PROBE_DETECT);
+ AddModuleOptions(*ploaderList, (*driver->AvailableOptions)(-1, -1));
+ }
+ else if (info && info->AvailableOptions)
+ AddModuleOptions(*ploaderList, (*info->AvailableOptions)(NULL));
+
+ if (!noverify) {
+ XF86ModuleData *initdata = NULL;
+ char *p;
+
+ p = XtMalloc(strlen(*ploaderList) + strlen("ModuleData") + 1);
+ strcpy(p, *ploaderList);
+ strcat(p, "ModuleData");
+ initdata = LoaderSymbol(p);
+ if (initdata) {
+ XF86ModuleVersionInfo *vers;
+
+ vers = initdata->vers;
+ if (vers && strcmp(*ploaderList, vers->modname)) {
+ /* This was a problem at some time for some video drivers */
+ CheckMsg(CHECKER_FILE_MODULE_NAME_MISMATCH,
+ "WARNING file/module name mismatch: \"%s\" \"%s\"\n",
+ *ploaderList, vers->modname);
+ ++error_level;
+ }
+ }
+ XtFree(p);
+ }
+
+ nfonts = numFontModules;
+ numFontModules = 0;
+ fonts = FontModuleList;
+ if (fonts) {
+ while (fonts->name) {
+ if (strcmp(fonts->name, *ploaderList) == 0)
+ pfont_module = fonts;
+ ++numFontModules;
+ ++fonts;
+ }
+ }
+ if (pfont_module)
+ module_type = FontRendererModule;
+ else if (nfonts + 1 <= numFontModules) {
+ /* loader.c will flag a warning if -noverify is not set */
+ pfont_module = &FontModuleList[nfonts];
+ module_type = FontRendererModule;
+ }
+
+ if (font_module) {
+ XtFree((XtPointer)font_module->name);
+ XtFree((XtPointer)font_module);
+ font_module = NULL;
+ }
+ if (pfont_module) {
+ font_module = XtNew(FontModule);
+ memcpy(font_module, pfont_module, sizeof(FontModule));
+ font_module->name = XtNewString(pfont_module->name);
+ }
+
+ UnloadModule(module);
+
+ return (1);
+}
+
+void
+xf86AddDriver(DriverPtr drv, void *module, int flags)
+{
+ driver = drv;
+ if (driver)
+ driver->module = module;
+ module_type = VideoModule;
+}
+
+Bool
+xf86ServerIsOnlyDetecting(void)
+{
+ return (True);
+}
+
+void
+xf86AddInputDriver(InputDriverPtr inp, void *module, int flags)
+{
+ module_type = InputModule;
+}
+
+void
+xf86AddModuleInfo(ModuleInfoPtr inf, void *module)
+{
+ info = inf;
+}
+
+Bool
+xf86LoaderCheckSymbol(const char *symbol)
+{
+ return LoaderSymbol(symbol) != NULL;
+}
+
+void
+xf86LoaderRefSymLists(const char **list0, ...)
+{
+}
+
+void
+xf86LoaderReqSymLists(const char **list0, ...)
+{
+}
+
+#if 0
+void xf86Msg(int type, const char *format, ...)
+{
+}
+#endif
+
+/*ARGSUSED*/
+void
+xf86PrintChipsets(const char *name, const char *msg, SymTabPtr chipsets)
+{
+ vendor = 0;
+ chips = chipsets;
+}
+
+pciVideoPtr *
+xf86GetPciVideoInfo(void)
+{
+ static pciVideoRec pci_video;
+ static pciVideoPtr pci_video_ptr[2] = { &pci_video };
+
+ memset(&pci_video, 0, sizeof(pciVideoRec));
+
+ return (pci_video_ptr);
+}
+
+int
+xf86MatchDevice(const char *name, GDevPtr **gdev)
+{
+ *gdev = NULL;
+
+ return (1);
+}
+
+int
+xf86MatchPciInstances(const char *name, int VendorID, SymTabPtr chipsets, PciChipsets *PCIchipsets,
+ GDevPtr *devList, int numDevs, DriverPtr drvp, int **foundEntities)
+{
+ vendor = VendorID;
+ if (chips == NULL)
+ chips = chipsets;
+ *foundEntities = NULL;
+
+ return (0);
+}
+
+int
+xf86MatchIsaInstances(const char *name, SymTabPtr chipsets, IsaChipsets *ISAchipsets, DriverPtr drvp,
+ FindIsaDevProc FindIsaDevice, GDevPtr *devList, int numDevs, int **foundEntities)
+{
+ *foundEntities = NULL;
+
+ return (0);
+}
+
+/*ARGSUSED*/
+void *
+xf86LoadDrvSubModule(DriverPtr drv, const char *name)
+{
+ pointer ret;
+ int errmaj = 0, errmin = 0;
+
+ ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
+ &errmaj, &errmin);
+ if (!ret)
+ LoaderErrorMsg(NULL, name, errmaj, errmin);
+ return (ret);
+}
+
+pciConfigPtr *
+xf86GetPciConfigInfo(void)
+{
+ return (NULL);
+}
+
+Bool
+xf86IsPrimaryPci(pciVideoPtr pPci)
+{
+ return (True);
+}
+#endif
diff --git a/hw/xfree86/utils/xorgcfg/monitor-cfg.c b/hw/xfree86/utils/xorgcfg/monitor-cfg.c
new file mode 100644
index 000000000..430833381
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/monitor-cfg.c
@@ -0,0 +1,449 @@
+/*
+ * 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/monitor-cfg.c,v 1.7 2001/03/24 01:17:20 paulo Exp $
+ */
+
+#include "xf86config.h"
+#include "monitor-cfg.h"
+#include "screen.h"
+#include <X11/extensions/xf86vmode.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Simple.h>
+
+#include <ctype.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/List.h>
+#include <X11/Xaw/MenuButton.h>
+#include <X11/Xaw/Viewport.h>
+#include <X11/Xaw/SimpleMenu.h>
+#include <X11/Xaw/SmeBSB.h>
+
+/*
+ * Prototypes
+ */
+static Bool MonitorConfigCheck(void);
+static void MonitorHsyncCallback(Widget, XtPointer, XtPointer);
+static void MonitorVsyncCallback(Widget, XtPointer, XtPointer);
+static void MonitorSelectCardCallback(Widget, XtPointer, XtPointer);
+
+extern void DrawCables(void);
+
+/*
+ * Initialization
+ */
+static char *hmodes[] = {
+ "Standard VGA, 640x480 @ 60 Hz",
+ "Super VGA, 800x600 @ 56 Hz",
+ "1024x768 @ 87 Hz int. (no 800x600)",
+ "1024x768 @ 87 Hz int., 800x600 @ 56 Hz",
+ "800x600 @ 60 Hz, 640x480 @ 72 Hz",
+ "1024x768 @ 60 Hz, 800x600 @ 72 Hz",
+ "High Frequency SVGA, 1024x768 @ 70 Hz",
+ "Monitor that can do 1280x1024 @ 60 Hz",
+ "Monitor that can do 1280x1024 @ 74 Hz",
+ "Monitor that can do 1280x1024 @ 76 Hz",
+};
+
+static char *hmodes_trans[] = {
+ "31.5",
+ "31.5 - 35.1",
+ "31.5, 35.5",
+ "31.5, 35.15, 35.5",
+ "31.5 - 37.9",
+ "31.5 - 48.5",
+ "31.5 - 57.0",
+ "31.5 - 64.3",
+ "31.5 - 79.0",
+ "31.5 - 82.0",
+};
+
+static char *vmodes [] = { "50 - 70", "50 - 90", "50 - 100", "40 - 150", };
+
+extern Widget config;
+static Widget hsync, vsync, hlist, vlist, cmenu;
+
+static parser_range mon_hsync[CONF_MAX_HSYNC];
+static parser_range mon_vrefresh[CONF_MAX_VREFRESH];
+static int mon_n_hsync, mon_n_vrefresh;
+static XF86ConfDevicePtr oldcard, card;
+static XF86ConfMonitorPtr current_monitor;
+
+/*
+ * Implementation
+ */
+XtPointer
+MonitorConfig(XtPointer conf)
+{
+ XF86ConfMonitorPtr monitor = (XF86ConfMonitorPtr)conf;
+ char monitor_name[48];
+ Arg args[1];
+
+ current_monitor = monitor;
+
+ xf86info.cur_list = MONITOR;
+ XtSetSensitive(back, xf86info.lists[MONITOR].cur_function > 0);
+ XtSetSensitive(next, xf86info.lists[MONITOR].cur_function <
+ xf86info.lists[MONITOR].num_functions - 1);
+ (xf86info.lists[MONITOR].functions[xf86info.lists[MONITOR].cur_function])
+ (&xf86info);
+
+ XawListUnhighlight(hlist);
+ XawListUnhighlight(vlist);
+
+ if (monitor != NULL) {
+ XF86ConfScreenPtr screen = XF86Config->conf_screen_lst;
+ char str[PARSER_RANGE_SIZE];
+
+ XtSetArg(args[0], XtNstring, monitor->mon_identifier);
+ XtSetValues(ident_widget, args, 1);
+
+ while (screen != NULL) {
+ if (screen->scrn_monitor == monitor)
+ break;
+
+ screen = (XF86ConfScreenPtr)(screen->list.next);
+ }
+ if (screen != NULL) {
+ oldcard = card = screen->scrn_device;
+ XtSetArg(args[0], XtNlabel, card->dev_identifier);
+ }
+ else {
+ oldcard = card = NULL;
+ XtSetArg(args[0], XtNlabel, "");
+ }
+ XtSetValues(cmenu, args, 1);
+
+ mon_n_hsync = monitor->mon_n_hsync;
+ memcpy(mon_hsync, monitor->mon_hsync,
+ sizeof(parser_range) * mon_n_hsync);
+ *str = '\0';
+ parser_range_to_string(str, mon_hsync, mon_n_hsync);
+ XtSetArg(args[0], XtNstring, str);
+ XtSetValues(hsync, args, 1);
+
+ mon_n_vrefresh = monitor->mon_n_vrefresh;
+ memcpy(mon_vrefresh, monitor->mon_vrefresh,
+ sizeof(parser_range) * mon_n_vrefresh);
+ *str = '\0';
+ parser_range_to_string(str, mon_vrefresh, mon_n_vrefresh);
+ XtSetArg(args[0], XtNstring, str);
+ XtSetValues(vsync, args, 1);
+ }
+ else {
+ XF86ConfMonitorPtr monitor = XF86Config->conf_monitor_lst;
+ int nmonitors = 0;
+
+ oldcard = card = NULL;
+ while (monitor != NULL) {
+ ++nmonitors;
+ monitor = (XF86ConfMonitorPtr)(monitor->list.next);
+ }
+ do {
+ XmuSnprintf(monitor_name, sizeof(monitor_name),
+ "Monitor%d", nmonitors);
+ ++nmonitors;
+ } while (xf86findMonitor(monitor_name,
+ XF86Config->conf_monitor_lst));
+
+ XtSetArg(args[0], XtNstring, monitor_name);
+ XtSetValues(ident_widget, args, 1);
+
+ XtSetArg(args[0], XtNstring, "");
+ XtSetValues(hsync, args, 1);
+ XtSetValues(vsync, args, 1);
+
+ XtSetArg(args[0], XtNlabel, "");
+ XtSetValues(cmenu, args, 1);
+ }
+
+ if (ConfigLoop(MonitorConfigCheck) == True) {
+ if (monitor == NULL) {
+ monitor = (XF86ConfMonitorPtr)
+ XtCalloc(1, sizeof(XF86ConfMonitorRec));
+ monitor->mon_identifier = XtNewString(ident_string);
+ }
+
+ memcpy(monitor->mon_hsync, mon_hsync, sizeof(parser_range) *
+ (monitor->mon_n_hsync = mon_n_hsync));
+ memcpy(monitor->mon_vrefresh, mon_vrefresh, sizeof(parser_range) *
+ (monitor->mon_n_vrefresh = mon_n_vrefresh));
+
+ if (strcasecmp(monitor->mon_identifier, ident_string))
+ xf86renameMonitor(XF86Config, monitor, ident_string);
+
+ if (oldcard != card) {
+ int i;
+
+ for (i = 0; i < computer.num_devices; i++)
+ if (computer.devices[i]->widget == config)
+ break;
+ if (computer.devices[i]->config == NULL)
+ XF86Config->conf_monitor_lst =
+ xf86addMonitor(XF86Config->conf_monitor_lst,
+ monitor);
+ computer.devices[i]->config = (XtPointer)monitor;
+ ChangeScreen(monitor, monitor, card, oldcard);
+ DrawCables();
+ }
+
+ return (monitor);
+ }
+
+ return (NULL);
+}
+
+static Bool
+MonitorConfigCheck(void)
+{
+ char *str;
+ Arg args[1];
+ XF86ConfMonitorPtr monitor = XF86Config->conf_monitor_lst;
+
+ if (ident_string == NULL || strlen(ident_string) == 0)
+ return (False);
+
+ bzero(mon_hsync, sizeof(parser_range) * CONF_MAX_HSYNC);
+ bzero(mon_vrefresh, sizeof(parser_range) * CONF_MAX_VREFRESH);
+
+ XtSetArg(args[0], XtNstring, &str);
+ XtGetValues(hsync, args, 1);
+ if ((mon_n_hsync = string_to_parser_range(str, mon_hsync,
+ CONF_MAX_HSYNC)) <= 0)
+ return (False);
+
+ XtSetArg(args[0], XtNstring, &str);
+ XtGetValues(vsync, args, 1);
+ if ((mon_n_vrefresh = string_to_parser_range(str, mon_vrefresh,
+ CONF_MAX_VREFRESH)) <= 0)
+ return (False);
+
+ while (monitor != NULL) {
+ if (monitor != current_monitor &&
+ strcasecmp(ident_string, monitor->mon_identifier) == 0)
+ return (False);
+ monitor = (XF86ConfMonitorPtr)(monitor->list.next);
+ }
+
+ return (True);
+}
+
+int
+string_to_parser_range(char *str, parser_range *range, int nrange)
+{
+ double val;
+ int i = 0;
+
+ if (str == NULL || *str == '\0' || range == NULL || nrange == 0)
+ return (0);
+
+ while (*str) {
+ while (*str && isspace(*str))
+ ++str;
+ if (!isdigit(*str)) {
+ ++str;
+ continue;
+ }
+ val = strtod(str, &str);
+ while (*str && isspace(*str))
+ ++str;
+ if (*str == ',' || *str == '\0') {
+ if (*str)
+ ++str;
+ range[i].lo = range[i].hi = val;
+ if (++i >= nrange || *str == '\0')
+ break;
+ continue;
+ }
+ else if (*str != '-')
+ return (0);
+ ++str;
+ range[i].lo = val;
+ while (*str && isspace(*str))
+ ++str;
+ if ((range[i].hi = strtod(str, &str)) < range[i].lo)
+ return (0);
+ if (++i >= nrange)
+ break;
+ }
+
+ return (i);
+}
+
+int
+parser_range_to_string(char *str, parser_range *range, int nrange)
+{
+ int i, len;
+
+ if (str == NULL || range == NULL || nrange <= 0)
+ return (0);
+
+ for (i = len = 0; i < nrange; i++) {
+ if (i > 0)
+ len += XmuSnprintf(str + len, PARSER_RANGE_SIZE - len, "%s",
+ ", ");
+ if (range[i].lo == range[i].hi)
+ len += XmuSnprintf(str + len, PARSER_RANGE_SIZE - len, "%g",
+ range[i].lo);
+ else if (range[i].lo < range[i].hi)
+ len += XmuSnprintf(str + len, PARSER_RANGE_SIZE - len, "%g - %g",
+ range[i].lo, range[i].hi);
+ else
+ return (0);
+ }
+
+ return (i);
+}
+
+/*ARGSUSED*/
+static void
+MonitorHsyncCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XawListReturnStruct *info = (XawListReturnStruct *)call_data;
+ Arg args[1];
+
+ XtSetArg(args[0], XtNstring, hmodes_trans[info->list_index]);
+ XtSetValues(hsync, args, 1);
+}
+
+/*ARGSUSED*/
+static void
+MonitorVsyncCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XawListReturnStruct *info = (XawListReturnStruct *)call_data;
+ Arg args[1];
+
+ XtSetArg(args[0], XtNstring, info->string);
+ XtSetValues(vsync, args, 1);
+}
+
+/*ARGSUSED*/
+static void
+MonitorSelectCardCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[1];
+
+ card = (XF86ConfDevicePtr)user_data;
+ XtSetArg(args[0], XtNlabel, card != NULL ? card->dev_identifier : "");
+ XtSetValues(cmenu, args, 1);
+}
+
+void
+MonitorLayout(XF86SetupInfo *info)
+{
+ static int first = 1, men;
+ static Widget layout, menu;
+ XF86ConfDevicePtr device = XF86Config->conf_device_lst;
+ Widget sme;
+ Arg args[1];
+ char *menuname;
+
+ if (first) {
+ Widget viewport;
+
+ first = 0;
+
+ layout = XtCreateWidget("monitorl", formWidgetClass,
+ configp, NULL, 0);
+ XtCreateManagedWidget("hlabel", labelWidgetClass, layout, NULL, 0);
+ hsync = XtVaCreateManagedWidget("hsync", asciiTextWidgetClass, layout,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ viewport = XtCreateManagedWidget("hviewport", viewportWidgetClass,
+ layout, NULL, 0);
+ hlist = XtVaCreateManagedWidget("hlist", listWidgetClass, viewport,
+ XtNlist, hmodes,
+ XtNnumberStrings, sizeof(hmodes) /
+ sizeof(hmodes[0]), NULL, 0);
+ XtAddCallback(hlist, XtNcallback, MonitorHsyncCallback, NULL);
+
+ XtCreateManagedWidget("vlabel", labelWidgetClass, layout, NULL, 0);
+ vsync = XtVaCreateManagedWidget("vsync", asciiTextWidgetClass, layout,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ viewport = XtCreateManagedWidget("vviewport", viewportWidgetClass,
+ layout, NULL, 0);
+ vlist = XtVaCreateManagedWidget("vlist", listWidgetClass, viewport,
+ XtNlist, vmodes,
+ XtNnumberStrings, sizeof(vmodes) /
+ sizeof(vmodes[0]), NULL, 0);
+ XtAddCallback(vlist, XtNcallback, MonitorVsyncCallback, NULL);
+
+ XtCreateManagedWidget("clabel", labelWidgetClass, layout, NULL, 0);
+ cmenu = XtCreateManagedWidget("cmenu", menuButtonWidgetClass,
+ layout, NULL, 0);
+
+ XtRealizeWidget(layout);
+ }
+
+ if (menu != NULL)
+ XtDestroyWidget(menu);
+
+ /*
+ * swaps names because XtDestroyWidget will only really destroy it
+ * when the code returns to XtAppMainLoop
+ */
+ menuname = men & 1 ? "mena" : "menb";
+ menu = XtCreatePopupShell(menuname, simpleMenuWidgetClass,
+ cmenu, NULL, 0);
+ XtSetArg(args[0], XtNmenuName, menuname);
+ XtSetValues(cmenu, args, 1);
+ ++men;
+ sme = XtVaCreateManagedWidget("none", smeBSBObjectClass, menu,
+ NULL, 0);
+ XtAddCallback(sme, XtNcallback, MonitorSelectCardCallback, NULL);
+
+ while (device != NULL) {
+ XF86ConfScreenPtr screen = XF86Config->conf_screen_lst;
+ Widget sme;
+ Bool sensitive = True;
+
+ while (screen != NULL) {
+ if (screen->scrn_device == device) {
+ sensitive = screen->scrn_monitor == NULL ||
+ screen->scrn_monitor == current_monitor;
+ break;
+ }
+ screen = (XF86ConfScreenPtr)(screen->list.next);
+ }
+ sme = XtCreateManagedWidget(device->dev_identifier,
+ smeBSBObjectClass, menu,
+ NULL, 0);
+ if (sensitive)
+ XtAddCallback(sme, XtNcallback, MonitorSelectCardCallback, device);
+ XtSetSensitive(sme, sensitive);
+
+ device = (XF86ConfDevicePtr)(device->list.next);
+ }
+
+ XtRealizeWidget(menu);
+
+ XtChangeManagedSet(&current, 1, NULL, NULL, &layout, 1);
+ current = layout;
+}
diff --git a/hw/xfree86/utils/xorgcfg/monitor-cfg.h b/hw/xfree86/utils/xorgcfg/monitor-cfg.h
new file mode 100644
index 000000000..03ca18a41
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/monitor-cfg.h
@@ -0,0 +1,48 @@
+/*
+ * 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/monitor-cfg.h,v 1.3 2000/11/30 20:55:18 paulo Exp $
+ */
+
+#include "config.h"
+
+#ifndef _xf86cfg_monitor_h
+#define _xf86cfg_monitor_h
+
+/*
+ * Prototypes
+ */
+XtPointer MonitorConfig(XtPointer);
+void MonitorLayout(XF86SetupInfo*);
+void MonitorVidtune(XF86SetupInfo*);
+int string_to_parser_range(char*, parser_range*, int);
+#define PARSER_RANGE_SIZE 256
+/* string must have at least 256 bytes */
+int parser_range_to_string(char*, parser_range*, int);
+
+#endif /* _xf86cfg_monitor_h */
diff --git a/hw/xfree86/utils/xorgcfg/monitor.xbm b/hw/xfree86/utils/xorgcfg/monitor.xbm
new file mode 100644
index 000000000..c4b01eb74
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/monitor.xbm
@@ -0,0 +1,59 @@
+/*
+ * 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/monitor.xbm,v 1.1 2000/04/04 22:37:00 dawes Exp $
+ */
+#define monitor_width 50
+#define monitor_height 44
+static unsigned char monitor_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0x03, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x1e, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x70,
+ 0xfc, 0xff, 0xff, 0xff, 0x38, 0x00, 0x30, 0xfe, 0xff, 0xff, 0xff, 0x31,
+ 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, 0x30, 0x03, 0x00, 0x00,
+ 0x00, 0x33, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, 0x30, 0x03,
+ 0x00, 0x00, 0x00, 0x33, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00,
+ 0x30, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00,
+ 0x33, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, 0x30, 0x03, 0x00,
+ 0x00, 0x00, 0x33, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, 0x30,
+ 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x33,
+ 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, 0x30, 0x03, 0x00, 0x00,
+ 0x00, 0x33, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, 0x30, 0x03,
+ 0x00, 0x00, 0x00, 0x33, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00,
+ 0x30, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00,
+ 0x33, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, 0x30, 0xfe, 0xff,
+ 0xff, 0xff, 0x31, 0x00, 0x70, 0xfc, 0xff, 0xff, 0xff, 0x38, 0x00, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x1e,
+ 0x00, 0xc0, 0x1f, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0x03, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0xc0, 0x0f,
+ 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
+ 0xf8, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x3f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
diff --git a/hw/xfree86/utils/xorgcfg/monitor.xpm b/hw/xfree86/utils/xorgcfg/monitor.xpm
new file mode 100644
index 000000000..c694edf2e
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/monitor.xpm
@@ -0,0 +1,79 @@
+/* XPM */
+/*
+ * 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/monitor.xpm,v 1.1 2000/04/04 22:37:00 dawes Exp $
+ */
+static char * monitor_xpm[] = {
+"47 40 6 1",
+" c none",
+"Z c #DF7DE38DDF7D",
+". c #BEFBBEFBBEFB",
+"X c #9E799A699E79",
+"o c #30C230C230C2",
+"O c #96589E799658",
+"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ..",
+"Z..............................................",
+"Z.............................................X",
+"Z.............................................X",
+"Z...XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.....X",
+"Z...Xooooooooooooooooooooooooooooooooooooo....X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z...XoooooooooooooooooooooooooooooooooooooZ...X",
+"Z....oooooooooooooooooooooooooooooooooooooZ...X",
+"Z.....ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ...X",
+"Z.............................................X",
+"Z.............................................X",
+"..............................................X",
+"..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+" OOOOOOOOOOOOOOOOOOOOOOOOOo ",
+" XXXXXXXXXXXXXXXXXXXXXXXXXX ",
+" OOOOOOXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo. ",
+" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
+" ooooooooooooooooooooooooooooooooooooooo "};
diff --git a/hw/xfree86/utils/xorgcfg/mouse-cfg.c b/hw/xfree86/utils/xorgcfg/mouse-cfg.c
new file mode 100644
index 000000000..761da248a
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/mouse-cfg.c
@@ -0,0 +1,450 @@
+/*
+ * 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/mouse-cfg.c,v 1.10 2003/02/15 05:37:58 paulo Exp $
+ */
+
+#include "xf86config.h"
+#include "mouse-cfg.h"
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/List.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Toggle.h>
+#include <X11/Xaw/Viewport.h>
+#include <X11/extensions/xf86misc.h>
+
+/*
+ * Prototypes
+ */
+static void MouseDeviceCallback(Widget, XtPointer, XtPointer);
+static void MouseProtocolCallback(Widget, XtPointer, XtPointer);
+static void MouseEmulateCallback(Widget, XtPointer, XtPointer);
+static void MouseApplyCallback(Widget, XtPointer, XtPointer);
+static Bool MouseConfigCheck(void);
+
+/*
+ * Initialization
+ */
+static struct MouseProtocol {
+ char *name;
+ int type;
+} protocols[] = {
+#ifdef SCO
+ {"OsMouse", MTYPE_AUTOMOUSE},
+#endif
+#ifdef WSCONS_SUPPORT
+ {"wsmouse", MTYPE_AUTOMOUSE},
+#endif
+ {"Auto", MTYPE_AUTOMOUSE},
+ {"SysMouse", MTYPE_SYSMOUSE},
+ {"MouseSystems", MTYPE_MOUSESYS},
+ {"BusMouse", MTYPE_BUSMOUSE},
+ {"PS/2", MTYPE_PS_2},
+ {"Microsoft", MTYPE_MICROSOFT},
+#ifndef __FreeBSD__
+ {"ImPS/2", MTYPE_IMPS2},
+ {"ExplorerPS/2", MTYPE_EXPPS2},
+ {"GlidePointPS/2", MTYPE_GLIDEPOINTPS2},
+ {"MouseManPlusPS/2", MTYPE_MMANPLUSPS2},
+ {"NetMousePS/2", MTYPE_NETPS2},
+ {"NetScrollPS/2", MTYPE_NETSCROLLPS2},
+ {"ThinkingMousePS/2", MTYPE_THINKINGPS2},
+#endif
+ {"AceCad", MTYPE_ACECAD},
+ {"GlidePoint", MTYPE_GLIDEPOINT},
+ {"IntelliMouse", MTYPE_IMSERIAL},
+ {"Logitech", MTYPE_LOGITECH},
+ {"MMHitTab", MTYPE_MMHIT},
+ {"MMSeries", MTYPE_MMSERIES},
+ {"MouseMan", MTYPE_LOGIMAN},
+ {"ThinkingMouse", MTYPE_THINKING},
+};
+
+static Widget text;
+static char *device, *protocol;
+static Bool emulate;
+static XF86ConfInputPtr current_input;
+
+/*
+ * Implementation
+ */
+/*ARGSUSED*/
+XtPointer
+MouseConfig(XtPointer config)
+{
+ XF86ConfInputPtr mouse = (XF86ConfInputPtr)config;
+ XF86OptionPtr option;
+ char mouse_name[32];
+ Arg args[1];
+
+ static char *Device = "Device", *Protocol = "Protocol",
+ *Emulate3Buttons = "Emulate3Buttons",
+ *Emulate3Timeout = "Emulate3Timeout";
+
+ current_input = mouse;
+
+ if (mouse != NULL) {
+ emulate = xf86findOption(mouse->inp_option_lst,
+ Emulate3Buttons) != NULL;
+ if ((option = xf86findOption(mouse->inp_option_lst, Device)) != NULL)
+ device = option->opt_val;
+ else
+ device = NULL;
+ if ((option = xf86findOption(mouse->inp_option_lst, Protocol)) != NULL)
+ protocol = option->opt_val;
+ else
+ protocol = NULL;
+
+ XtSetArg(args[0], XtNstring, mouse->inp_identifier);
+ XtSetValues(ident_widget, args, 1);
+ }
+ else {
+ XF86ConfInputPtr input = XF86Config->conf_input_lst;
+ int nmouses = 0;
+
+ while (input != NULL) {
+ if (strcasecmp(input->inp_driver, "mouse") == 0)
+ ++nmouses;
+ input = (XF86ConfInputPtr)(input->list.next);
+ }
+ do {
+ XmuSnprintf(mouse_name, sizeof(mouse_name), "Mouse%d", nmouses);
+ ++nmouses;
+ } while (xf86findInput(mouse_name,
+ XF86Config->conf_input_lst));
+
+ XtSetArg(args[0], XtNstring, mouse_name);
+ XtSetValues(ident_widget, args, 1);
+
+ emulate = True;
+ device = NULL;
+ protocol = NULL;
+ }
+
+ xf86info.cur_list = MOUSE;
+ XtSetSensitive(back, xf86info.lists[MOUSE].cur_function > 0);
+ XtSetSensitive(next, xf86info.lists[MOUSE].cur_function <
+ xf86info.lists[MOUSE].num_functions - 1);
+ (xf86info.lists[MOUSE].functions[xf86info.lists[MOUSE].cur_function])
+ (&xf86info);
+
+ if (ConfigLoop(MouseConfigCheck) == True) {
+ XtSetArg(args[0], XtNstring, &device);
+ XtGetValues(text, args, 1);
+ if (mouse == NULL) {
+ mouse = XtNew(XF86ConfInputRec);
+ mouse->list.next = NULL;
+ mouse->inp_identifier = XtNewString(ident_string);
+ mouse->inp_driver = XtNewString("mouse");
+ mouse->inp_option_lst = xf86newOption(XtNewString(Device),
+ XtNewString(device));
+ xf86addNewOption(mouse->inp_option_lst,
+ XtNewString(Protocol), XtNewString(protocol));
+ if (emulate) {
+ xf86addNewOption(mouse->inp_option_lst,
+ XtNewString(Emulate3Buttons), NULL);
+ xf86addNewOption(mouse->inp_option_lst,
+ XtNewString(Emulate3Timeout),
+ XtNewString("50"));
+ }
+ mouse->inp_comment = NULL;
+ }
+ else {
+ if ((option = xf86findOption(mouse->inp_option_lst, Device)) != NULL) {
+ XtFree(option->opt_val);
+ option->opt_val = XtNewString(device);
+ XtFree(option->opt_comment);
+ }
+ else {
+ if (mouse->inp_option_lst == NULL)
+ mouse->inp_option_lst = xf86newOption(XtNewString(Device),
+ XtNewString(device));
+ else
+ xf86addNewOption(mouse->inp_option_lst,
+ XtNewString(Device), XtNewString(device));
+ }
+
+ if ((option = xf86findOption(mouse->inp_option_lst, Protocol)) != NULL) {
+ XtFree(option->opt_val);
+ option->opt_val = XtNewString(protocol);
+ XtFree(option->opt_comment);
+ }
+ else
+ xf86addNewOption(mouse->inp_option_lst,
+ XtNewString(Protocol), XtNewString(protocol));
+
+ if (emulate == False) {
+ xf86removeOption(&(mouse->inp_option_lst), Emulate3Buttons);
+ xf86removeOption(&(mouse->inp_option_lst), Emulate3Timeout);
+ }
+ else if (emulate) {
+ xf86addNewOption(mouse->inp_option_lst,
+ XtNewString(Emulate3Buttons), NULL);
+ xf86addNewOption(mouse->inp_option_lst,
+ XtNewString(Emulate3Timeout), XtNewString("50"));
+ }
+ }
+ if (strcasecmp(mouse->inp_identifier, ident_string))
+ xf86renameInput(XF86Config, mouse, ident_string);
+
+ return ((XtPointer)mouse);
+ }
+
+ return (NULL);
+}
+
+static Bool
+MouseConfigCheck(void)
+{
+ Arg args[1];
+ XF86ConfInputPtr mouse = XF86Config->conf_input_lst;
+
+ XtSetArg(args[0], XtNstring, &device);
+ XtGetValues(text, args, 1);
+
+ if (ident_string == NULL || strlen(ident_string) == 0 ||
+ device == NULL || strlen(device) == 0 || protocol == NULL)
+ return (False);
+ while (mouse != NULL) {
+ if (mouse != current_input &&
+ strcasecmp(ident_string, mouse->inp_identifier) == 0)
+ return (False);
+ mouse = (XF86ConfInputPtr)(mouse->list.next);
+ }
+
+ return (True);
+}
+
+static void
+MouseDeviceCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XawListReturnStruct *info = (XawListReturnStruct *)call_data;
+ Arg args[1];
+
+ XtSetArg(args[0], XtNstring, info->string);
+ XtSetValues((Widget)user_data, args, 1);
+ XawTextSetInsertionPoint((Widget)user_data, strlen(info->string));
+}
+
+static void
+MouseProtocolCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XawListReturnStruct *info = (XawListReturnStruct *)call_data;
+
+ protocol = info->string;
+}
+
+static void
+MouseEmulateCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ emulate = (Bool)(long)call_data;
+}
+
+static void
+MouseApplyCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ int i;
+ XF86MiscMouseSettings mouse;
+
+ XF86MiscGetMouseSettings(XtDisplay(w), &mouse);
+ XtFree(mouse.device);
+
+ if (mouse.baudrate == 0 || mouse.baudrate < 0 || mouse.baudrate > 9600 ||
+ mouse.baudrate % 1200)
+ mouse.baudrate = 1200;
+
+ mouse.type = MTYPE_AUTOMOUSE;
+ for (i = 0; i < sizeof(protocols) / sizeof(protocols[0]); i++)
+ if (strcmp(protocols[i].name, protocol) == 0) {
+ mouse.type = protocols[i].type;
+ break;
+ }
+
+ mouse.emulate3buttons = emulate;
+ mouse.flags |= MF_REOPEN;
+
+ mouse.device = device;
+
+ XFlush(XtDisplay(w));
+ XF86MiscSetMouseSettings(XtDisplay(w), &mouse);
+}
+
+void
+MouseDeviceAndProtocol(XF86SetupInfo *info)
+{
+ static int first = 1, ndevices;
+ static Widget mouse_dp, listD, listP, emul3, apply;
+ static char **devices;
+ static char *dirs[] = {
+ "/dev",
+#ifdef __linux__
+ "/dev/input"
+#endif
+ };
+ static char *patterns[] = {
+#ifdef WSCONS_SUPPORT
+ "wsmouse",
+#endif
+ "cuaa",
+ "mice",
+ "mouse",
+ "ps",
+ "sysmouse",
+ "ttyS",
+ };
+ Arg args[2];
+ int i;
+
+ if (first) {
+ Widget label, viewport;
+ struct dirent *ent;
+ DIR *dir;
+ char **list;
+ int count;
+
+ first = 0;
+
+ mouse_dp = XtCreateWidget("mouseDP", formWidgetClass,
+ configp, NULL, 0);
+
+ /* DEVICE */
+ for (count = 0; count < sizeof(dirs) / sizeof(dirs[0]); count++) {
+ if ((dir = opendir(dirs[count])) != NULL) {
+ int i, len, xlen = strlen(dirs[count]) + 2;
+
+ (void)readdir(dir);
+ (void)readdir(dir);
+ while ((ent = readdir(dir)) != NULL) {
+ for (i = 0; i < sizeof(patterns) / sizeof(patterns[0]); i++) {
+ len = strlen(patterns[i]);
+
+ if (strncmp(patterns[i], ent->d_name, len) == 0) {
+ len = strlen(ent->d_name) + xlen;
+
+ devices = (char**)XtRealloc((XtPointer)devices,
+ sizeof(char*) * ++ndevices);
+ devices[ndevices - 1] = XtMalloc(len);
+ XmuSnprintf(devices[ndevices - 1], len, "%s/%s",
+ dirs[count], ent->d_name);
+ }
+ }
+ }
+ closedir(dir);
+ }
+ }
+
+ label = XtCreateManagedWidget("labelD", labelWidgetClass,
+ mouse_dp, NULL, 0);
+ text = XtVaCreateManagedWidget("device", asciiTextWidgetClass,
+ mouse_dp,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ viewport = XtCreateManagedWidget("viewportD", viewportWidgetClass,
+ mouse_dp, NULL, 0);
+
+ listD = XtVaCreateManagedWidget("listD", listWidgetClass,
+ viewport,
+ XtNlist, devices,
+ XtNnumberStrings, ndevices,
+ NULL, 0);
+ XtAddCallback(listD, XtNcallback, MouseDeviceCallback, (XtPointer)text);
+
+ /* PROTOCOL */
+ label = XtCreateManagedWidget("labelP", labelWidgetClass,
+ mouse_dp, NULL, 0);
+ viewport = XtCreateManagedWidget("viewportP", viewportWidgetClass,
+ mouse_dp, NULL, 0);
+
+ list = (char**)XtMalloc(sizeof(char*) *
+ sizeof(protocols)/sizeof(protocols[0]));
+ for (count = 0; count < sizeof(protocols)/sizeof(protocols[0]); count++)
+ list[count] = XtNewString(protocols[count].name);
+ listP = XtVaCreateManagedWidget("listP", listWidgetClass,
+ viewport,
+ XtNlist, list,
+ XtNnumberStrings, count,
+ NULL, 0);
+ XtAddCallback(listP, XtNcallback, MouseProtocolCallback, NULL);
+
+ emul3 = XtVaCreateManagedWidget("emulate3", toggleWidgetClass,
+ mouse_dp, XtNstate, True, NULL, 0);
+ XtAddCallback(emul3, XtNcallback, MouseEmulateCallback, NULL);
+ apply = XtCreateManagedWidget("apply", commandWidgetClass,
+ mouse_dp, NULL, 0);
+ XtAddCallback(apply, XtNcallback, MouseApplyCallback, NULL);
+
+ XtRealizeWidget(mouse_dp);
+ }
+
+ if (device != NULL) {
+ for (i = 0; i < ndevices; i++)
+ if (strcmp(device, devices[i]) == 0) {
+ XtSetArg(args[0], XtNstring, device);
+ XtSetValues(text, args, 1);
+ XawListHighlight(listD, i);
+ break;
+ }
+
+ if (i >= ndevices) {
+ devices = (char**)XtRealloc((XtPointer)devices,
+ sizeof(char*) * ++ndevices);
+ devices[ndevices - 1] = XtNewString(device);
+ XawListHighlight(listD, ndevices - 1);
+ XtSetArg(args[0], XtNlist, devices);
+ XtSetArg(args[1], XtNnumberStrings, ndevices);
+ XtSetValues(listD, args, 2);
+ }
+ device = devices[i];
+ }
+ else {
+ XtSetArg(args[0], XtNstring, "");
+ XtSetValues(text, args, 1);
+ XawListUnhighlight(listD);
+ }
+
+ if (protocol != NULL) {
+ for (i = 0; i < sizeof(protocols) / sizeof(protocols[0]); i++)
+ if (strcasecmp(protocol, protocols[i].name) == 0) {
+ protocol = protocols[i].name;
+ XawListHighlight(listP, i);
+ break;
+ }
+ }
+ else {
+ /* "Auto" is the default */
+ protocol = protocols[0].name;
+ XawListHighlight(listP, 0);
+ }
+
+ XtSetArg(args[0], XtNstate, emulate);
+ XtSetValues(emul3, args, 1);
+
+ XtChangeManagedSet(&current, 1, NULL, NULL, &mouse_dp, 1);
+ current = mouse_dp;
+}
diff --git a/hw/xfree86/utils/xorgcfg/mouse-cfg.h b/hw/xfree86/utils/xorgcfg/mouse-cfg.h
new file mode 100644
index 000000000..249f50840
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/mouse-cfg.h
@@ -0,0 +1,44 @@
+/*
+ * 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/mouse-cfg.h,v 1.1 2000/04/04 22:37:00 dawes Exp $
+ */
+
+#include "config.h"
+
+#ifndef _xf86cfg_mouse_h
+#define _xf86cfg_mouse_h
+
+/*
+ * Prototypes
+ */
+XtPointer MouseConfig(XtPointer);
+void MouseDeviceAndProtocol(XF86SetupInfo*);
+
+#endif /* _xf86cfg_mouse_h */
+
diff --git a/hw/xfree86/utils/xorgcfg/mouse.xbm b/hw/xfree86/utils/xorgcfg/mouse.xbm
new file mode 100644
index 000000000..8577137e6
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/mouse.xbm
@@ -0,0 +1,59 @@
+/*
+ * 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/mouse.xbm,v 1.1 2000/04/04 22:37:01 dawes Exp $
+ */
+#define mouse_width 50
+#define mouse_height 44
+static unsigned char mouse_bits[] = {
+ 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xcf, 0x03, 0x00,
+ 0x00, 0x00, 0xc0, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xe0, 0x79, 0x78,
+ 0x1e, 0x00, 0x00, 0x00, 0x60, 0x38, 0x70, 0x18, 0x00, 0x00, 0x00, 0x70,
+ 0x30, 0x30, 0x38, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00,
+ 0x00, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30,
+ 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x30, 0x30,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
+ 0xf0, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x3f, 0x00,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x38,
+ 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0xe0, 0x01,
+ 0x00, 0x1e, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
diff --git a/hw/xfree86/utils/xorgcfg/mouse.xpm b/hw/xfree86/utils/xorgcfg/mouse.xpm
new file mode 100644
index 000000000..7ad21fb8f
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/mouse.xpm
@@ -0,0 +1,76 @@
+/* XPM */
+/*
+ * 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/mouse.xpm,v 1.1 2000/04/04 22:37:01 dawes Exp $
+ */
+static char * mouse_xpm[] = {
+"26 35 8 1",
+" c none",
+". c #E79DE79DE79D",
+"X c #CF3CCF3CCF3C",
+"o c #BEFBBAEABEFB",
+"O c #8E3896588E38",
+"+ c #AEBAAAAAAEBA",
+"@ c #9E79AAAA9E79",
+"# c #A699A289A699",
+" .....XXXX. ",
+" X..o.XXXXXXXo... ",
+" X..XXo.XXXXXXXo.XX.X ",
+" X.XXXXo.XXXXXXXo.XXX.X ",
+" .XXXXXo.XXXXXXXo.XXXXoo ",
+" X.XXXXXo.XXXoXXXo.XXXXoXo",
+"oX.XXXXXo.XXXXXXXo.XXXXXoo",
+"oX.XoXoXo.XXoXoXXo.XXXXXoO",
+"oX.XXXXXo.XXXXXXXo.XXoXX+O",
+"oX.XXXoXo.XXoXoXXo.XXXXX+O",
+"oX.XXXXXo.XXXXXXXo.XX...+O",
+"ooooo...o........oooo@@@OO",
+"oX.XX#@@@@@@@@@@@@@@@XXX+O",
+"oX.XXXXXXXXXXXXXXXXXXXXX+O",
+"oX.XXXXXXXXXXXXXXXXXXXXX+O",
+"oX.XXXXXXXXXXXXXXXXXXXXX+O",
+"oX.XXXXXXXXXXXXXXXXXXXXX+O",
+"oX.XXXXXXXXXXXXXXXXXXXXX+O",
+"oX.XXXXXXXXXXXXXXXXXXXXX+O",
+"oX.XXXXXXXXXXXXXXXXXXXXX+O",
+"oX.XXXXXXXXXXXXXXXXXXXXX+O",
+"oX.XXXXXXXXXXXXXXXXXXXX+oO",
+" #X.XXXXXXXXXXXXXXXXXXooO ",
+" #X.XXXXXXXXXXXXXXXXXXooO ",
+" #X.XXXXXXXXXXXXXXXXXX+oO ",
+" #X.XXXXXXXXXXXXXXXXXX+oO ",
+" #.XXXXXXXXXXXXXXXXX++O ",
+" #X..XXXXXXXXXXXXXXX+oO ",
+" #X.XXXXXXXXXXXXXX+oO ",
+" #.XXXXXXXXXXXXXX+O ",
+" #X..XXXXXXXXXo++oO ",
+" #XX..XXXXXoo+ooO ",
+" ##XXooooo+ooOO ",
+" ooooooooOO ",
+" oOOOOO "};
diff --git a/hw/xfree86/utils/xorgcfg/narrower.xbm b/hw/xfree86/utils/xorgcfg/narrower.xbm
new file mode 100644
index 000000000..0649ef8b4
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/narrower.xbm
@@ -0,0 +1,8 @@
+#define narrower_width 19
+#define narrower_height 19
+static unsigned char narrower_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x00, 0x18, 0xc0, 0x00,
+ 0x38, 0xe0, 0x00, 0x78, 0xf0, 0x00, 0xf8, 0xf8, 0x00, 0xff, 0xfd, 0x07,
+ 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, 0xff, 0xfd, 0x07,
+ 0xf8, 0xf8, 0x00, 0x78, 0xf0, 0x00, 0x38, 0xe0, 0x00, 0x18, 0xc0, 0x00,
+ 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/hw/xfree86/utils/xorgcfg/options.c b/hw/xfree86/utils/xorgcfg/options.c
new file mode 100644
index 000000000..10828a94a
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/options.c
@@ -0,0 +1,788 @@
+/*
+ * 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/options.c,v 1.12 2001/11/03 20:32:31 paulo Exp $
+ */
+
+#include "options.h"
+#include "xf86config.h"
+#include <X11/Xresource.h>
+#include <X11/Shell.h>
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/List.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/MenuButton.h>
+#include <X11/Xaw/Paned.h>
+#include <X11/Xaw/SimpleMenP.h>
+#include <X11/Xaw/SmeBSB.h>
+#include <X11/Xaw/Viewport.h>
+#include <ctype.h>
+
+/*
+ * Prototypes
+ */
+static void PopdownCallback(Widget, XtPointer, XtPointer);
+static void SelectOptionCallback(Widget, XtPointer, XtPointer);
+static void AddOption(Widget, XtPointer, XtPointer);
+static void RemoveOption(Widget, XtPointer, XtPointer);
+static void UpdateOption(Widget, XtPointer, XtPointer);
+static void UpdateOptionList(void);
+#ifdef USE_MODULES
+static void AddDriverOption(Widget, XtPointer, XtPointer);
+static void SelectModuleCallback(Widget, XtPointer, XtPointer);
+static void SelectModuleOptionCallback(Widget, XtPointer, XtPointer);
+static void ModuleOptionsPopdown(Widget, XtPointer, XtPointer);
+#endif
+static Bool EnumDatabase(XrmDatabase*, XrmBindingList, XrmQuarkList,
+ XrmRepresentation*, XrmValue*, XPointer);
+
+/*
+ * Initialization
+ */
+Widget optionsShell;
+static XF86OptionPtr *options;
+static Widget add, remov, update, list, name, value;
+static char *option_str;
+static int option_index, popped = False;
+static char *Options = "lib/X11/Options";
+XrmDatabase options_xrm;
+struct {
+ char *string;
+ int offset;
+} rebuild_xrm;
+#ifdef USE_MODULES
+static Widget modList, optList, desc, modOptionsShell, labelType;
+static char *module_sel;
+static char *types[] = {
+ "none", "integer", "(non null) string", "string", "real",
+ "boolean", "frequency",
+};
+#endif
+
+/*
+ * Implementation
+ */
+#ifdef USE_MODULES
+static int
+qcmp_str(_Xconst void *a, _Xconst void *b)
+{
+ return (strcmp(*(char**)a, *(char**)b));
+}
+
+void
+ModuleOptionsPopup(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ xf86cfgModuleOptions *info = module_options;
+
+ if (modOptionsShell == NULL) {
+ char **ops;
+ int nops;
+ Widget pane, form, viewport, bottom, popdown;
+
+ modOptionsShell = XtCreatePopupShell("moduleOptions",
+ transientShellWidgetClass,
+ optionsShell, NULL, 0);
+
+ pane = XtCreateManagedWidget("pane", panedWidgetClass,
+ modOptionsShell, NULL, 0);
+
+ form = XtCreateManagedWidget("descriptions", formWidgetClass,
+ pane, NULL, 0);
+ labelType = XtCreateManagedWidget("labelType", labelWidgetClass,
+ form, NULL, 0);
+ XtCreateManagedWidget("module", labelWidgetClass, form, NULL, 0);
+ viewport = XtCreateManagedWidget("viewM", viewportWidgetClass,
+ form, NULL, 0);
+ ops = NULL;
+ nops = 0;
+ while (info) {
+ ++nops;
+ ops = (char**)XtRealloc((XtPointer)ops, sizeof(char*) * nops);
+ ops[nops - 1] = XtNewString(info->name);
+ info = info->next;
+ }
+ if (nops == 0) {
+ ops = (char**)XtMalloc(sizeof(char*));
+ ops[0] = XtNewString("");
+ nops = 1;
+ }
+ else
+ qsort(ops, nops, sizeof(char*), qcmp_str);
+ modList = XtVaCreateManagedWidget("modL", listWidgetClass,
+ viewport, XtNlist, ops,
+ XtNnumberStrings, nops,
+ NULL, 0);
+ XtAddCallback(modList, XtNcallback, SelectModuleCallback, NULL);
+ XtCreateManagedWidget("option", labelWidgetClass, form, NULL, 0);
+ viewport = XtCreateManagedWidget("viewO", viewportWidgetClass,
+ form, NULL, 0);
+ ops = (char**)XtMalloc(sizeof(char*));
+ ops[0] = XtNewString("");
+ optList = XtVaCreateManagedWidget("optL", listWidgetClass,
+ viewport, XtNlist, ops,
+ XtNnumberStrings, 1, NULL, 0);
+ XtAddCallback(optList, XtNcallback, SelectModuleOptionCallback, NULL);
+ desc = XtVaCreateManagedWidget("desc", asciiTextWidgetClass,
+ form, XtNeditType, XawtextRead,
+ NULL, 0);
+
+ bottom = XtCreateManagedWidget("bottom", formWidgetClass,
+ pane, NULL, 0);
+ popdown = XtVaCreateManagedWidget("popdown", commandWidgetClass,
+ bottom, NULL, 0);
+ XtAddCallback(popdown, XtNcallback, ModuleOptionsPopdown, NULL);
+ XtRealizeWidget(modOptionsShell);
+ XSetWMProtocols(DPY, XtWindow(modOptionsShell), &wm_delete_window, 1);
+
+ info = module_options;
+ }
+
+ if (module_sel && *module_sel) {
+ XawListReturnStruct list; /* hack to call ballbacks */
+ char **strs;
+ int nstrs, idx = 0;
+
+ XtVaGetValues(modList, XtNlist, &strs, XtNnumberStrings, &nstrs, NULL);
+ for (idx = nstrs - 1; idx > 0; idx--)
+ if (strcmp(module_sel, strs[idx]) == 0)
+ break;
+ while (info) {
+ if (strcmp(module_sel, info->name) == 0)
+ break;
+ info = info->next;
+ }
+ if (info) {
+ list.string = info->name;
+ list.list_index = idx;
+ XawListHighlight(modList, idx);
+ SelectModuleCallback(modList, NULL, (XtPointer)&list);
+ }
+ if (option_str && *option_str) {
+ OptionInfoPtr opts = info->option;
+
+ idx = 0;
+ while (opts && opts->name) {
+ if (strcmp(opts->name, option_str) == 0)
+ break;
+ ++idx;
+ ++opts;
+ }
+
+ if (opts && opts->name) {
+ list.string = (char *)opts->name;
+ list.list_index = idx;
+ XawListHighlight(optList, idx);
+ SelectModuleOptionCallback(optList, NULL, (XtPointer)&list);
+ }
+ }
+ }
+ XtPopup(modOptionsShell, XtGrabNone);
+}
+
+/*ARGSUSED*/
+static void
+ModuleOptionsPopdown(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XtPopdown(modOptionsShell);
+}
+
+/*ARGSUSED*/
+void
+ModuleOptionsCancelAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ ModuleOptionsPopdown(w, NULL, NULL);
+}
+#endif
+
+void
+CreateOptionsShell(void)
+{
+ optionsShell = XtCreatePopupShell("options", transientShellWidgetClass,
+ toplevel, NULL, 0);
+}
+
+#ifdef USE_MODULES
+void
+OptionsPopup(XF86OptionPtr *opts, char *driver, OptionInfoPtr drv_opts)
+#else
+void
+OptionsPopup(XF86OptionPtr *opts)
+#endif
+{
+ static int first = 1;
+#ifdef USE_MODULES
+ static Widget button, menu;
+ static char label[256], menuName[16];
+ Widget sme;
+ char buf[256];
+ int i = 0;
+ Arg args[1];
+ static int menuN;
+#endif
+
+ option_str = NULL;
+ options = opts;
+ if (first) {
+ Widget pane, form, viewport, bottom, popdown;
+
+ first = 0;
+
+ if (optionsShell == NULL)
+ CreateOptionsShell();
+ pane = XtCreateManagedWidget("pane", panedWidgetClass,
+ optionsShell, NULL, 0);
+
+ form = XtCreateManagedWidget("commands", formWidgetClass,
+ pane, NULL, 0);
+ add = XtCreateManagedWidget("add", commandWidgetClass,
+ form, NULL, 0);
+ XtAddCallback(add, XtNcallback, AddOption, NULL);
+ remov = XtCreateManagedWidget("remove", commandWidgetClass,
+ form, NULL, 0);
+ XtAddCallback(remov, XtNcallback, RemoveOption, NULL);
+ update = XtCreateManagedWidget("update", commandWidgetClass,
+ form, NULL, 0);
+ XtAddCallback(update, XtNcallback, UpdateOption, NULL);
+#ifdef USE_MODULES
+ if (!nomodules) {
+ Widget command;
+
+ command = XtCreateManagedWidget("help", commandWidgetClass,
+ form, NULL, 0);
+ XtAddCallback(command, XtNcallback, ModuleOptionsPopup, NULL);
+ }
+#endif
+ form = XtCreateManagedWidget("form", formWidgetClass,
+ pane, NULL, 0);
+ XtVaCreateManagedWidget("label1", labelWidgetClass, form,
+ XtNlabel, " Option \"",
+ NULL, 0);
+ name = XtVaCreateManagedWidget("name", asciiTextWidgetClass, form,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ XtVaCreateManagedWidget("label2", labelWidgetClass,
+ form,
+ XtNlabel, "\" \"",
+ NULL, 0);
+ value = XtVaCreateManagedWidget("value", asciiTextWidgetClass, form,
+ XtNeditType, XawtextEdit,
+ NULL, 0);
+ XtVaCreateManagedWidget("label3", labelWidgetClass, form,
+ XtNlabel, "\" ",
+ NULL, 0);
+ viewport = XtCreateManagedWidget("viewport", viewportWidgetClass,
+ form, NULL, 0);
+ list = XtCreateManagedWidget("list", listWidgetClass,
+ viewport, NULL, 0);
+ XtAddCallback(list, XtNcallback, SelectOptionCallback, NULL);
+ bottom = XtCreateManagedWidget("bottom", formWidgetClass,
+ pane, NULL, 0);
+#ifdef USE_MODULES
+ if (!nomodules)
+ button = XtCreateManagedWidget("driverOpts", menuButtonWidgetClass,
+ bottom, NULL, 0);
+#endif
+ popdown = XtVaCreateManagedWidget("popdown", commandWidgetClass,
+ bottom, NULL, 0);
+#ifdef USE_MODULES
+ if (!nomodules)
+ XtVaSetValues(popdown, XtNfromHoriz, button, NULL, 0);
+#endif
+
+ XtAddCallback(popdown, XtNcallback, PopdownCallback, NULL);
+ XtRealizeWidget(optionsShell);
+ XSetWMProtocols(DPY, XtWindow(optionsShell), &wm_delete_window, 1);
+
+#ifdef USE_MODULES
+ if (!nomodules) {
+ char *str;
+
+ XtSetArg(args[0], XtNlabel, &str);
+ XtGetValues(button, args, 1);
+ XmuSnprintf(label, sizeof(label), "%s", str);
+ }
+#endif
+ }
+
+#ifdef USE_MODULES
+ if (!nomodules) {
+ if (menu)
+ XtDestroyWidget(menu);
+ XmuSnprintf(menuName, sizeof(buf), "optionM%d", menuN);
+ menuN = !menuN;
+ menu = XtCreatePopupShell(menuName, simpleMenuWidgetClass, button,
+ NULL, 0);
+ XtVaSetValues(button, XtNmenuName, menuName, NULL, 0);
+ if (drv_opts) {
+ int len, longest = 0;
+ char fmt[32];
+
+ for (i = 0; drv_opts[i].name != NULL; i++) {
+ len = strlen(drv_opts[i].name);
+ if (len > longest)
+ longest = len;
+ }
+ XmuSnprintf(fmt, sizeof(fmt), "%c-%ds %%s", '%', longest);
+ for (; drv_opts->name != NULL; drv_opts++) {
+ char *type;
+
+ if (drv_opts->type >= OPTV_NONE && drv_opts->type <= OPTV_FREQ)
+ type = types[drv_opts->type];
+ else
+ type = "UNKNOWN";
+
+ XmuSnprintf(buf, sizeof(buf), fmt, drv_opts->name, type);
+ sme = XtVaCreateManagedWidget(drv_opts->name, smeBSBObjectClass,
+ menu, XtNlabel, buf, NULL, 0);
+ XtAddCallback(sme, XtNcallback, AddDriverOption, (XtPointer)drv_opts);
+ }
+ }
+ if (i) {
+ xf86cfgModuleOptions *mod = module_options;
+
+ while (mod) {
+ if (strcmp(mod->name, driver) == 0) {
+ /* don't assign to driver, as it may be a temp string */
+ module_sel = mod->name;
+ break;
+ }
+ mod = mod->next;
+ }
+ XmuSnprintf(buf, sizeof(buf), "%s%s", label, driver);
+ XtSetArg(args[0], XtNlabel, buf);
+ XtSetValues(button, args, 1);
+ XtMapWidget(button);
+ }
+ else
+ XtUnmapWidget(button);
+ }
+#endif
+
+ UpdateOptionList();
+ popped = True;
+ XtPopup(optionsShell, XtGrabExclusive);
+
+ while (popped)
+ XtAppProcessEvent(XtWidgetToApplicationContext(optionsShell), XtIMAll);
+}
+
+static void
+UpdateOptionList(void)
+{
+ Arg args[2];
+ char **ops, **oldops;
+ int nops, oldnops;
+ XF86OptionPtr opt;
+
+ ops = NULL;
+ nops = 0;
+ XawListUnhighlight(list);
+ XtSetArg(args[0], XtNlist, &oldops);
+ XtSetArg(args[1], XtNnumberStrings, &oldnops);
+ XtGetValues(list, args, 2);
+ opt = *options;
+ while (opt != NULL) {
+ if (nops % 16 == 0)
+ ops = (char**)XtRealloc((XtPointer)ops, (nops + 16) *
+ sizeof(char*));
+ ops[nops++] = XtNewString(opt->opt_name);
+ opt = (XF86OptionPtr)(opt->list.next);
+ }
+ if (nops == 0) {
+ ops = (char**)XtMalloc(sizeof(char*));
+ ops[0] = XtNewString("");
+ nops = 1;
+ }
+ XtSetArg(args[0], XtNlist, ops);
+ XtSetArg(args[1], XtNnumberStrings, nops);
+ XtSetValues(list, args, 2);
+ if (oldnops > 0 &&
+ (oldnops != 1 || XtName(list) != oldops[0])) {
+ while (--oldnops >= 0)
+ XtFree(oldops[oldnops]);
+ XtFree((XtPointer)oldops);
+ }
+
+ XtSetArg(args[0], XtNstring, "");
+ XtSetValues(name, args, 1);
+ XtSetValues(value, args, 1);
+
+ /* force relayout */
+ XtUnmanageChild(list);
+ XtManageChild(list);
+
+ XtSetSensitive(remov, False);
+ XtSetSensitive(update, False);
+}
+
+/*ARGSUSED*/
+static void
+PopdownCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XtPopdown(optionsShell);
+ popped = False;
+}
+
+/*ARGSUSED*/
+void
+OptionsCancelAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ PopdownCallback(w, NULL, NULL);
+}
+
+/*ARGSUSED*/
+static void
+SelectOptionCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[1];
+ XF86OptionPtr option;
+ XawListReturnStruct *info = (XawListReturnStruct *)call_data;
+
+ option_str = info->string;
+ option_index = info->list_index;
+ if ((option = xf86findOption(*options, info->string)) != NULL) {
+ XtSetArg(args[0], XtNstring, option->opt_name);
+ XtSetValues(name, args, 1);
+ XtSetArg(args[0], XtNstring,
+ option->opt_val != NULL ? option->opt_val : "");
+ XtSetValues(value, args, 1);
+ }
+ XtSetSensitive(remov, True);
+ XtSetSensitive(update, True);
+}
+
+/*ARGSUSED*/
+static void
+AddOption(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[1];
+ char *nam, *val;
+
+ XtSetArg(args[0], XtNstring, &nam);
+ XtGetValues(name, args, 1);
+ XtSetArg(args[0], XtNstring, &val);
+ XtGetValues(value, args, 1);
+ if (xf86findOption(*options, nam) != NULL || strlen(nam) == 0)
+ /* XXX xf86addNewOption will trash the option linked list if
+ * the options being added already exists.
+ */
+ return;
+ *options = xf86addNewOption(*options, XtNewString(nam),
+ val && strlen(val) ? XtNewString(val) : NULL);
+ UpdateOptionList();
+}
+
+#ifdef USE_MODULES
+/*ARGSUSED*/
+static void
+AddDriverOption(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[1];
+ OptionInfoPtr opt = (OptionInfoPtr)user_data;
+ XF86OptionPtr option;
+
+ option_str = (char *)opt->name;
+ XtSetArg(args[0], XtNstring, opt->name);
+ XtSetValues(name, args, 1);
+ if ((option = xf86findOption(*options, opt->name)) == NULL)
+ XtSetArg(args[0], XtNstring, "");
+ else
+ XtSetArg(args[0], XtNstring, option->opt_val);
+ XtSetValues(value, args, 1);
+}
+
+/*ARGSUSED*/
+static void
+SelectModuleCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ xf86cfgModuleOptions *mod = module_options;
+ XawListReturnStruct *info = (XawListReturnStruct *)call_data;
+
+ while (mod) {
+ if (strcmp(mod->name, info->string) == 0)
+ break;
+ mod = mod->next;
+ }
+
+ if (mod) {
+ Arg args[2];
+ char **list = NULL, **old;
+ OptionInfoPtr opts = mod->option;
+ int num = 0, oldnum;
+
+ module_sel = mod->name;
+ XtSetArg(args[0], XtNlist, &old);
+ XtSetArg(args[1], XtNnumberStrings, &oldnum);
+ XtGetValues(optList, args, 2);
+ while (opts && opts->name) {
+ ++num;
+ list = (char**)XtRealloc((XtPointer)list, sizeof(char*) * num);
+ list[num - 1] = XtNewString(opts->name);
+ ++opts;
+ }
+ if (num == 0) {
+ list = (char**)XtMalloc(sizeof(char*));
+ list[0] = XtNewString("");
+ num = 1;
+ }
+ XtSetArg(args[0], XtNlist, list);
+ XtSetArg(args[1], XtNnumberStrings, num);
+ XtSetValues(optList, args, 2);
+ while (--oldnum >= 0)
+ XtFree(old[oldnum]);
+ XtFree((XtPointer)old);
+
+ XtVaSetValues(desc, XtNstring, "", NULL);
+ XawListUnhighlight(optList);
+
+ /* force relayout */
+ XtUnmanageChild(optList);
+ XtManageChild(optList);
+ }
+}
+
+static void
+SelectModuleOptionCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ xf86cfgModuleOptions *mod = module_options;
+ XawListReturnStruct *info = (XawListReturnStruct *)call_data;
+ char *description = NULL, *type = "undefined";
+ char label[256];
+
+ if (module_sel && info->string)
+ description = GetOptionDescription(module_sel, info->string);
+ if (description == NULL)
+ description = "** NO DESCRIPTION AVAILABLE **";
+
+ XtVaSetValues(desc, XtNstring, description, NULL);
+
+ while (mod) {
+ if (strcmp(module_sel, mod->name) == 0)
+ break;
+ mod = mod->next;
+ }
+ if (mod) {
+ OptionInfoPtr opts = mod->option;
+
+ while (opts && opts->name) {
+ if (strcasecmp(opts->name, info->string) == 0)
+ break;
+ ++opts;
+ }
+ if (opts && opts->name && opts->type >= OPTV_NONE &&
+ opts->type <= OPTV_FREQ)
+ type = types[opts->type];
+ }
+
+ XmuSnprintf(label, sizeof(label), "%s.%s (%s)", module_sel, info->string,
+ type);
+ XtVaSetValues(labelType, XtNlabel, label, NULL);
+}
+#endif
+
+/*ARGSUSED*/
+static void
+RemoveOption(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[1];
+ char *str;
+
+ XtSetArg(args[0], XtNstring, &str);
+ XtGetValues(name, args, 1);
+ xf86removeOption(options, str);
+ UpdateOptionList();
+}
+
+/*ARGSUSED*/
+static void
+UpdateOption(Widget w, XtPointer user_data, XtPointer call_data)
+{
+/* xf86removeOption(options, option_str);
+ AddOption(w, user_data, call_data);
+ UpdateOptionList();*/
+
+ Arg args[1];
+ char *nam, *val;
+ XF86OptionPtr option;
+
+ XtSetArg(args[0], XtNstring, &nam);
+ XtGetValues(name, args, 1);
+ XtSetArg(args[0], XtNstring, &val);
+ XtGetValues(value, args, 1);
+ if ((option = xf86findOption(*options, option_str)) == NULL)
+ return;
+ XtFree(option->opt_name);
+ option->opt_name = option_str = XtNewString(nam);
+ XtFree(option->opt_val);
+ if (val && strlen(val))
+ option->opt_val = XtNewString(val);
+ else
+ option->opt_val = NULL;
+
+ UpdateOptionList();
+ XawListHighlight(list, option_index);
+ XtSetArg(args[0], XtNstring, option->opt_name);
+ XtSetValues(name, args, 1);
+ XtSetArg(args[0], XtNstring, option->opt_val);
+ XtSetValues(value, args, 1);
+
+ XtSetSensitive(remov, True);
+ XtSetSensitive(update, True);
+}
+
+/*ARGUSED*/
+static Bool
+EnumDatabase(XrmDatabase *db, XrmBindingList bindings, XrmQuarkList quarks,
+ XrmRepresentation *type, XrmValue *value, XPointer closure)
+{
+ char *module = XrmQuarkToString(quarks[0]),
+ *option = XrmQuarkToString(quarks[1]);
+
+ /* handle *.Option: value */
+ if (module && option == NULL) {
+ option = module;
+ module = "*";
+ }
+
+ /*
+ * NOTE: If the Options file is changed to support any other format than
+ *
+ * Module.Option: description text
+ *
+ * this code will also need to be updated.
+ */
+
+ if (module) {
+ XrmValue xrm;
+ char *type, *value, query[256];
+
+ XmuSnprintf(query, sizeof(query), "%s.%s", module, option);
+ if (XrmGetResource(options_xrm, query, "Module.Option", &type, &xrm))
+ value = (char*)xrm.addr;
+ else
+ value = NULL;
+
+ if (value) {
+ char *norm;
+ unsigned char *ptr;
+ int position;
+ int length = strlen(module) + strlen(option) + strlen(value) + 4;
+
+ rebuild_xrm.string = XtRealloc(rebuild_xrm.string,
+ rebuild_xrm.offset + length);
+ position = rebuild_xrm.offset +
+ sprintf(rebuild_xrm.string + rebuild_xrm.offset, "%s.%s:",
+ module, option);
+
+ /* removes underlines and spaces */
+ norm = strchr(rebuild_xrm.string + rebuild_xrm.offset, '.') + 1;
+ for (; *norm; norm++) {
+ if (*norm == '_' || *norm == ' ' || *norm == '\t') {
+ memmove(norm, norm + 1, strlen(norm) + 1);
+ --position;
+ --length;
+ }
+ }
+
+ for (ptr = (unsigned char*)rebuild_xrm.string + rebuild_xrm.offset;
+ *ptr; ptr++)
+ *ptr = tolower(*ptr);
+ sprintf(rebuild_xrm.string + position, "%s\n", value);
+ rebuild_xrm.offset += length - 1;
+ }
+ }
+
+ return (False);
+}
+
+Bool
+InitializeOptionsDatabase(void)
+{
+ static int first = 1;
+ static Bool result = True;
+
+ if (first) {
+ XrmQuark names[2];
+ XrmQuark classes[2];
+
+ first = 0;
+ XrmInitialize();
+ if ((options_xrm = XrmGetFileDatabase(Options)) == (XrmDatabase)0) {
+ fprintf(stderr, "Cannot open '%s' database.\n", Options);
+ return (False);
+ }
+
+ /* rebuild database, using only lowercase characters */
+ names[0] = classes[0] = names[1] = classes[1] = NULLQUARK;
+ (void)XrmEnumerateDatabase(options_xrm, (XrmNameList)&names,
+ (XrmClassList)&classes, XrmEnumAllLevels,
+ EnumDatabase, NULL);
+
+ /* free previous database, as it is not guaranteed to be
+ * "case insensitive" */
+ XrmDestroyDatabase(options_xrm);
+
+ /* create case insensitive database by making everything lowercase */
+ if (rebuild_xrm.string == NULL ||
+ (options_xrm = XrmGetStringDatabase(rebuild_xrm.string)) ==
+ (XrmDatabase)0) {
+ fprintf(stderr, "Cannot rebuild '%s' database.\n", Options);
+ XtFree(rebuild_xrm.string);
+ return (False);
+ }
+ XtFree(rebuild_xrm.string);
+ }
+
+ return (result);
+}
+
+char *
+GetOptionDescription(char *module, char *option)
+{
+ char *type;
+ XrmValue value;
+ char query[256];
+ unsigned char *ptr;
+
+ InitializeOptionsDatabase();
+
+ XmuSnprintf(query, sizeof(query), "%s.%s", module, option);
+ ptr = (unsigned char*)strchr(query, '.') + 1;
+ for (; *ptr; ptr++) {
+ if (*ptr == '_' || *ptr == ' ' || *ptr == '\t')
+ memmove(ptr, ptr + 1, strlen((char*)ptr) + 1);
+ }
+ for (ptr = (unsigned char*)query; *ptr; ptr++)
+ *ptr = tolower(*ptr);
+ if (XrmGetResource(options_xrm, query, "Module.Option", &type, &value))
+ return ((char*)value.addr);
+
+ return (NULL);
+}
diff --git a/hw/xfree86/utils/xorgcfg/options.h b/hw/xfree86/utils/xorgcfg/options.h
new file mode 100644
index 000000000..a90072607
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/options.h
@@ -0,0 +1,51 @@
+/*
+ * 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/options.h,v 1.7 2001/07/06 02:04:10 paulo Exp $
+ */
+
+#include "config.h"
+#ifdef USE_MODULES
+#include "loader.h"
+#endif
+
+/*
+ * Prototypes
+ */
+#ifdef USE_MODULES
+void OptionsPopup(XF86OptionPtr*, char*, OptionInfoPtr);
+void ModuleOptionsPopup(Widget, XtPointer, XtPointer);
+#else
+void OptionsPopup(XF86OptionPtr*);
+#endif
+void OptionsCancelAction(Widget, XEvent*, String*, Cardinal*);
+void ModuleOptionsCancelAction(Widget, XEvent*, String*, Cardinal*);
+char *GetOptionDescription(char *module, char *option);
+Bool InitializeOptionsDatabase(void);
+
+void CreateOptionsShell(void);
diff --git a/hw/xfree86/utils/xorgcfg/right.xbm b/hw/xfree86/utils/xorgcfg/right.xbm
new file mode 100644
index 000000000..a2f2ce2d1
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/right.xbm
@@ -0,0 +1,8 @@
+#define right_width 19
+#define right_height 19
+static unsigned char right_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00,
+ 0x00, 0x0e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x3e, 0x00, 0xf8, 0x7f, 0x00,
+ 0xf8, 0xff, 0x00, 0xf8, 0xff, 0x01, 0xf8, 0xff, 0x00, 0xf8, 0x7f, 0x00,
+ 0x00, 0x3e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x06, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/hw/xfree86/utils/xorgcfg/screen-cfg.c b/hw/xfree86/utils/xorgcfg/screen-cfg.c
new file mode 100644
index 000000000..5aa71188a
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/screen-cfg.c
@@ -0,0 +1,552 @@
+/*
+ * 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/screen-cfg.c,v 1.12 2002/11/18 05:24:18 paulo Exp $
+ */
+
+#include "xf86config.h"
+#include "screen-cfg.h"
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/List.h>
+#include <X11/Xaw/Toggle.h>
+#include <X11/Xaw/Viewport.h>
+#ifdef USE_MODULES
+#include "loader.h"
+#endif
+
+#define CW 1
+#define CCW -1
+
+/*
+ * Prototypes
+ */
+static void DepthCallback(Widget, XtPointer, XtPointer);
+static void SelectIndexCallback(Widget, XtPointer, XtPointer);
+static void UnselectIndexCallback(Widget, XtPointer, XtPointer);
+static void SelectCallback(Widget, XtPointer, XtPointer);
+static void UnselectCallback(Widget, XtPointer, XtPointer);
+static void MoveCallback(Widget, XtPointer, XtPointer);
+static void RotateCallback(Widget, XtPointer, XtPointer);
+
+/*
+ * Initialization
+ */
+static char *standard_modes[] = {
+ "640x400",
+ "640x480",
+ "800x600",
+ "1024x768",
+ "1280x960",
+ "1280x1024",
+ "320x200",
+ "320x240",
+ "400x300",
+ "1152x864",
+ "1600x1200",
+ "1800x1400",
+ "512x384",
+ "1400x1050",
+};
+
+static char **modes;
+static int nmodes;
+static int default_depth, sel_index, unsel_index;
+static Widget listL, listR;
+static char **defmodes;
+static int ndefmodes;
+static XF86ConfScreenPtr screen;
+static int rotate;
+
+/*
+ * Implementation
+ */
+XtPointer
+ScreenConfig(XtPointer conf)
+{
+ XF86ConfDisplayPtr disp;
+ Arg args[2];
+ int i, oldrotate;
+
+ screen = (XF86ConfScreenPtr)conf;
+ if (screen == NULL)
+ return (NULL);
+
+ XtSetArg(args[0], XtNstring, screen->scrn_identifier);
+ XtSetValues(ident_widget, args, 1);
+ if ((default_depth = screen->scrn_defaultdepth) <= 0)
+ default_depth = 8;
+ sel_index = unsel_index = -1;
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->screen == screen) {
+ SetScreenRotate(computer.screens[i]);
+ rotate = computer.screens[i]->rotate;
+ }
+ oldrotate = rotate;
+
+ ndefmodes = 0;
+ disp = screen->scrn_display_lst;
+ while (disp != NULL) {
+ if (disp->disp_depth == default_depth) {
+ XF86ModePtr mod = disp->disp_mode_lst;
+
+ while (mod != NULL) {
+ if (ndefmodes % 16 == 0)
+ defmodes = (char**)
+ XtRealloc((XtPointer)defmodes,
+ (ndefmodes + 16) * sizeof(char*));
+ defmodes[ndefmodes++] = XtNewString(mod->mode_name);
+ mod = (XF86ModePtr)(mod->list.next);
+ }
+ break;
+ }
+ disp = (XF86ConfDisplayPtr)(disp->list.next);
+ }
+ if (ndefmodes == 0) {
+ defmodes = (char**)XtMalloc(sizeof(char*));
+ defmodes[0] = XtNewString("640x480");
+ ndefmodes = 1;
+ }
+
+ if (listL != NULL) {
+ XawListUnhighlight(listL);
+ XawListUnhighlight(listR);
+ }
+
+ xf86info.cur_list = SCREEN;
+ XtSetSensitive(back, xf86info.lists[SCREEN].cur_function > 0);
+ XtSetSensitive(next, xf86info.lists[SCREEN].cur_function <
+ xf86info.lists[SCREEN].num_functions - 1);
+ (xf86info.lists[SCREEN].functions[xf86info.lists[SCREEN].cur_function])
+ (&xf86info);
+
+ if (ConfigLoop(NULL) == True) {
+ XF86ModePtr prev = NULL, mod;
+
+ /* user may have changed the default depth, read variables again */
+ disp = screen->scrn_display_lst;
+ while (disp != NULL) {
+ if (disp->disp_depth == default_depth)
+ break;
+ disp = (XF86ConfDisplayPtr)(disp->list.next);
+ }
+
+ if (disp == NULL) {
+ disp = (XF86ConfDisplayPtr)XtCalloc(1, sizeof(XF86ConfDisplayRec));
+ screen->scrn_display_lst = (XF86ConfDisplayPtr)
+ xf86addListItem((GenericListPtr)(screen->scrn_display_lst),
+ (GenericListPtr)(disp));
+ disp->disp_depth = default_depth;
+ }
+
+ if (strcasecmp(screen->scrn_identifier, ident_string))
+ xf86renameScreen(XF86Config, screen, ident_string);
+
+ screen->scrn_defaultdepth = default_depth;
+
+ XtSetArg(args[0], XtNlist, NULL);
+ XtSetArg(args[1], XtNnumberStrings, 0);
+ XtSetValues(listL, args, 2);
+
+ XtSetArg(args[0], XtNlist, NULL);
+ XtSetArg(args[1], XtNnumberStrings, 0);
+ XtSetValues(listR, args, 2);
+
+ mod = disp->disp_mode_lst;
+ /* free all modes */
+ while (mod != NULL) {
+ prev = mod;
+ mod = (XF86ModePtr)(mod->list.next);
+ XtFree(prev->mode_name);
+ XtFree((XtPointer)prev);
+ }
+ /* readd modes */
+ for (i = 0; i < ndefmodes; i++) {
+ mod = XtNew(XF86ModeRec);
+ mod->mode_name = XtNewString(defmodes[i]);
+ XtFree(defmodes[i]);
+ if (i == 0)
+ disp->disp_mode_lst = mod;
+ else
+ prev->list.next = mod;
+ prev = mod;
+ }
+ if (i == 0)
+ disp->disp_mode_lst = NULL;
+ else
+ mod->list.next = NULL;
+
+ XtFree((XtPointer)defmodes);
+ defmodes = NULL;
+ ndefmodes = 0;
+
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->screen == screen)
+ computer.screens[i]->rotate = rotate;
+
+ if (oldrotate != rotate) {
+ static char *Rotate = "Rotate";
+
+ if (screen->scrn_option_lst != NULL)
+ xf86removeOption(&screen->scrn_option_lst, Rotate);
+ if (rotate)
+ screen->scrn_option_lst =
+ xf86addNewOption(screen->scrn_option_lst,
+ XtNewString(Rotate),
+ XtNewString(rotate > 0 ? "CW" : "CCW"));
+ UpdateScreenUI();
+ AdjustScreenUI();
+ }
+
+ return ((XtPointer)screen);
+ }
+
+ XtSetArg(args[0], XtNlist, NULL);
+ XtSetArg(args[1], XtNnumberStrings, 0);
+ XtSetValues(listL, args, 2);
+
+ XtSetArg(args[0], XtNlist, NULL);
+ XtSetArg(args[1], XtNnumberStrings, 0);
+ XtSetValues(listR, args, 2);
+
+ for (i = 0; i < ndefmodes; i++)
+ XtFree(defmodes[i]);
+ XtFree((XtPointer)defmodes);
+ defmodes = NULL;
+ ndefmodes = 0;
+
+ return (NULL);
+}
+
+/*ARGSUSED*/
+static void
+DepthCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ if (call_data != NULL)
+ default_depth = (long)user_data;
+}
+
+/*ARGSUSED*/
+static void
+SelectIndexCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XawListReturnStruct *info = (XawListReturnStruct *)call_data;
+
+ sel_index = info->list_index;
+}
+
+/*ARGSUSED*/
+static void
+UnselectIndexCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ XawListReturnStruct *info = (XawListReturnStruct *)call_data;
+
+ unsel_index = info->list_index;
+}
+
+/*ARGSUSED*/
+static void
+SelectCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[2];
+
+ if (sel_index < 0 || sel_index >= nmodes)
+ return;
+
+ if (ndefmodes == 1 && *defmodes[0] == '\0') {
+ /* make sure tmp and defentries are not the same pointer */
+ char **tmp = defmodes;
+
+ XtFree(defmodes[0]);
+ defmodes = (char**)XtMalloc(sizeof(char*));
+ --ndefmodes;
+ XtFree((char*)tmp);
+ }
+ else
+ defmodes = (char**)XtRealloc((XtPointer)defmodes,
+ sizeof(char*) * (ndefmodes + 1));
+ defmodes[ndefmodes++] = XtNewString(modes[sel_index]);
+
+ XtSetArg(args[0], XtNlist, defmodes);
+ XtSetArg(args[1], XtNnumberStrings, ndefmodes);
+ XtSetValues(listR, args, 2);
+
+ XawListUnhighlight(listR);
+ if (ndefmodes > 1 || (ndefmodes == 1 && *defmodes[0] != '\0')) {
+ if (unsel_index >= ndefmodes)
+ unsel_index = ndefmodes - 1;
+ XawListHighlight(listR, unsel_index = ndefmodes - 1);
+ }
+ else
+ unsel_index = -1;
+
+ /* force realyout */
+ XtUnmanageChild(listR);
+ XtManageChild(listR);
+}
+
+/*ARGSUSED*/
+static void
+UnselectCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ Arg args[2];
+ char **modes;
+ Cardinal num_modes;
+
+ if (unsel_index < 0 || unsel_index >= ndefmodes)
+ return;
+
+ XawListUnhighlight(listL);
+ XtSetArg(args[0], XtNlist, &modes);
+ XtSetArg(args[1], XtNnumberStrings, &num_modes);
+ XtGetValues(listL, args, 2);
+ if (modes) {
+ for (sel_index = 0; sel_index < num_modes; sel_index++)
+ if (strcmp(defmodes[unsel_index], modes[sel_index]) == 0)
+ break;
+ if (sel_index < num_modes)
+ XawListHighlight(listL, sel_index);
+ else
+ sel_index = -1;
+ }
+
+ XtFree(defmodes[unsel_index]);
+ if (--ndefmodes > unsel_index)
+ memmove(&defmodes[unsel_index], &defmodes[unsel_index + 1],
+ (ndefmodes - unsel_index) * sizeof(char*));
+ if (ndefmodes == 0) {
+ char **tmp = defmodes;
+
+ defmodes = (char**)XtMalloc(sizeof(char*));
+ defmodes[0] = XtNewString("");
+ ndefmodes = 1;
+ XtFree((char*)tmp);
+ }
+
+ XtSetArg(args[0], XtNlist, defmodes);
+ XtSetArg(args[1], XtNnumberStrings, ndefmodes);
+ XtSetValues(listR, args, 2);
+
+ XawListUnhighlight(listR);
+ if (ndefmodes > 1 || (ndefmodes == 1 && *defmodes[0] != '\0')) {
+ if (unsel_index >= ndefmodes)
+ unsel_index = ndefmodes - 1;
+ XawListHighlight(listR, unsel_index);
+ }
+ else
+ unsel_index = -1;
+}
+
+/*ARGSUSED*/
+static void
+MoveCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ char *tmp;
+ Bool down = (long)user_data;
+
+ if (unsel_index < 0 || unsel_index >= ndefmodes)
+ return;
+
+ if ((down && unsel_index + 1 >= ndefmodes) ||
+ (!down && unsel_index - 1 < 0))
+ return;
+
+ tmp = defmodes[unsel_index];
+ if (down) {
+ defmodes[unsel_index] = defmodes[unsel_index + 1];
+ unsel_index++;
+ } else {
+ defmodes[unsel_index] = defmodes[unsel_index - 1];
+ unsel_index--;
+ }
+ defmodes[unsel_index] = tmp;
+
+ XawListUnhighlight(listR);
+ XawListHighlight(listR, unsel_index);
+}
+
+/*ARGSUSED*/
+void
+RotateCallback(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ if (call_data != NULL)
+ rotate = (long)user_data;
+ else
+ rotate = 0;
+}
+
+void
+ScreenDialog(XF86SetupInfo *info)
+{
+ static Widget dialog, d1, d4, d8, d16, d24, labelRotate, cw, ccw;
+ Arg args[2];
+ XF86ConfMonitorPtr mon = screen->scrn_monitor;
+ XF86ConfModeLinePtr mline = mon != NULL ? mon->mon_modeline_lst : NULL;
+ int i;
+#ifdef USE_MODULES
+ xf86cfgModuleOptions *drv_opts = module_options;
+ Bool foundRotate = False;
+#endif
+
+ while (nmodes > 0)
+ XtFree(modes[--nmodes]);
+ XtFree((XtPointer)modes);
+ modes = NULL;
+ while (mline) {
+ if (nmodes % 16 == 0)
+ modes = (char**)XtRealloc((XtPointer)modes,
+ sizeof(char*) * (nmodes + 16));
+ modes[nmodes++] = XtNewString(mline->ml_identifier);
+ mline = (XF86ConfModeLinePtr)(mline->list.next);
+ }
+ for (i = 0; i < sizeof(standard_modes) / sizeof(standard_modes[0]); i++) {
+ if (nmodes % 16 == 0)
+ modes = (char**)XtRealloc((XtPointer)modes,
+ sizeof(char*) * (nmodes + 16));
+ modes[nmodes++] = XtNewString(standard_modes[i]);
+ }
+
+ if (dialog == NULL) {
+ Widget command, viewport;
+
+ dialog = XtCreateWidget("screenD", formWidgetClass,
+ configp, NULL, 0);
+ XtCreateManagedWidget("depthL", labelWidgetClass,
+ dialog, NULL, 0);
+ d1 = XtCreateManagedWidget("1", toggleWidgetClass, dialog, NULL, 0);
+ XtAddCallback(d1, XtNcallback, DepthCallback, (XtPointer)1);
+ d4 = XtVaCreateManagedWidget("4", toggleWidgetClass, dialog,
+ XtNradioGroup, d1, NULL, 0);
+ XtAddCallback(d4, XtNcallback, DepthCallback, (XtPointer)4);
+ d8 = XtVaCreateManagedWidget("8", toggleWidgetClass, dialog,
+ XtNradioGroup, d4, NULL, 0);
+ XtAddCallback(d8, XtNcallback, DepthCallback, (XtPointer)8);
+ d16 = XtVaCreateManagedWidget("16", toggleWidgetClass, dialog,
+ XtNradioGroup, d8, NULL, 0);
+ XtAddCallback(d16, XtNcallback, DepthCallback, (XtPointer)16);
+ d24 = XtVaCreateManagedWidget("24", toggleWidgetClass, dialog,
+ XtNradioGroup, d16, NULL, 0);
+ XtAddCallback(d24, XtNcallback, DepthCallback, (XtPointer)24);
+
+ XtCreateManagedWidget("modeL", labelWidgetClass, dialog, NULL, 0);
+ viewport = XtCreateManagedWidget("viewL", viewportWidgetClass, dialog,
+ NULL, 0);
+ listL = XtCreateManagedWidget("listLeft", listWidgetClass, viewport,
+ NULL, 0);
+ XtAddCallback(listL, XtNcallback, SelectIndexCallback, NULL);
+ command = XtCreateManagedWidget("select", commandWidgetClass,
+ dialog, NULL, 0);
+ XtAddCallback(command, XtNcallback, SelectCallback, NULL);
+ command = XtCreateManagedWidget("unselect", commandWidgetClass,
+ dialog, NULL, 0);
+ XtAddCallback(command, XtNcallback, UnselectCallback, NULL);
+ command = XtCreateManagedWidget("up", commandWidgetClass,
+ dialog, NULL, 0);
+ XtAddCallback(command, XtNcallback, MoveCallback, (XtPointer)False);
+ command = XtCreateManagedWidget("down", commandWidgetClass,
+ dialog, NULL, 0);
+ XtAddCallback(command, XtNcallback, MoveCallback, (XtPointer)True);
+ viewport = XtCreateManagedWidget("viewR", viewportWidgetClass, dialog,
+ NULL, 0);
+ listR = XtCreateManagedWidget("listRight", listWidgetClass, viewport,
+ NULL, 0);
+ XtAddCallback(listR, XtNcallback, UnselectIndexCallback, NULL);
+
+ labelRotate = XtCreateManagedWidget("rotate", labelWidgetClass,
+ dialog, NULL, 0);
+ cw = XtCreateManagedWidget("CW", toggleWidgetClass, dialog, NULL, 0);
+ XtAddCallback(cw, XtNcallback, RotateCallback, (XtPointer)CW);
+ ccw = XtVaCreateManagedWidget("CCW", toggleWidgetClass, dialog,
+ XtNradioGroup, cw, NULL, 0);
+ XtAddCallback(ccw, XtNcallback, RotateCallback, (XtPointer)CCW);
+
+ XtRealizeWidget(dialog);
+ }
+
+#ifdef USE_MODULES
+ if (!nomodules) {
+ while (drv_opts) {
+ if (drv_opts->type == VideoModule &&
+ strcmp(drv_opts->name, screen->scrn_device->dev_driver) == 0) {
+ OptionInfoPtr opts = drv_opts->option;
+
+ while (opts->name) {
+ if (xf86nameCompare(opts->name, "Rotate") == 0) {
+ foundRotate = True;
+ break;
+ }
+ opts++;
+ }
+ break;
+ }
+ drv_opts = drv_opts->next;
+ }
+
+ if (!foundRotate) {
+ XtUnmapWidget(labelRotate);
+ XtUnmapWidget(cw);
+ XtUnmapWidget(ccw);
+ }
+ else {
+ XtMapWidget(labelRotate);
+ XtMapWidget(cw);
+ XtMapWidget(ccw);
+ }
+ }
+#endif
+ if (rotate == CW) {
+ XtVaSetValues(cw, XtNstate, True, NULL, 0);
+ XtVaSetValues(ccw, XtNstate, False, NULL, 0);
+ }
+ else if (rotate == CCW) {
+ XtVaSetValues(cw, XtNstate, False, NULL, 0);
+ XtVaSetValues(ccw, XtNstate, True, NULL, 0);
+ }
+ else {
+ XtVaSetValues(cw, XtNstate, False, NULL, 0);
+ XtVaSetValues(ccw, XtNstate, False, NULL, 0);
+ }
+
+ XtSetArg(args[0], XtNlist, modes);
+ XtSetArg(args[1], XtNnumberStrings, nmodes);
+ XtSetValues(listL, args, 2);
+
+ XtSetArg(args[0], XtNlist, defmodes);
+ XtSetArg(args[1], XtNnumberStrings, ndefmodes);
+ XtSetValues(listR, args, 2);
+
+ XtSetArg(args[0], XtNstate, True);
+ XtSetValues(default_depth == 1 ? d1 :
+ default_depth == 4 ? d4 :
+ default_depth == 16 ? d16 :
+ default_depth == 24 ? d24 : d8, args, 1);
+
+ XtChangeManagedSet(&current, 1, NULL, NULL, &dialog, 1);
+ current = dialog;
+}
diff --git a/hw/xfree86/utils/xorgcfg/screen-cfg.h b/hw/xfree86/utils/xorgcfg/screen-cfg.h
new file mode 100644
index 000000000..a152f6188
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/screen-cfg.h
@@ -0,0 +1,44 @@
+/*
+ * 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/screen-cfg.h,v 1.2 2000/05/18 16:29:59 dawes Exp $
+ */
+
+#include "config.h"
+#include "screen.h"
+
+#ifndef _xf86cfg_screencfg_h
+#define _xf86cfg_screencfg_h
+
+/*
+ * Prototypes
+ */
+XtPointer ScreenConfig(XtPointer);
+void ScreenDialog(XF86SetupInfo*);
+
+#endif /* _xf86cfg_screencfg_h */
diff --git a/hw/xfree86/utils/xorgcfg/screen.c b/hw/xfree86/utils/xorgcfg/screen.c
new file mode 100644
index 000000000..25fd5f290
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/screen.c
@@ -0,0 +1,984 @@
+/*
+ * 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/screen.c,v 1.9 2002/06/06 21:03:32 paulo Exp $
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/extensions/shape.h>
+#include <X11/Xaw/Simple.h>
+#include "screen.h"
+
+#define CW 1
+#define CCW -1
+
+/*
+ * Prototypes
+ */
+void ReshapeScreenWidget(xf86cfgScreen*);
+static int qcmp_screen(_Xconst void*, _Xconst void*);
+
+/*
+ * Initialization
+ */
+extern Widget work;
+
+static int rows, columns; /* number of rows/columns of monitors */
+
+static int mon_width, mon_height;
+static int *mon_widths, *mon_heights;
+
+/*
+ * Implementation
+ */
+void
+SetScreenRotate(xf86cfgScreen *screen)
+{
+ static char *Rotate = "Rotate", *_CW = "CW", *_CCW = "CCW";
+ int rotate = 0;
+ XF86OptionPtr option, options;
+
+ /* This is the only place where xf86cfg is intrusive, and deletes options
+ * added by the user directly in the config file. The "Rotate" option
+ * will be kept in the screen section.
+ */
+ if (screen->monitor != NULL) {
+ options = ((XF86ConfMonitorPtr)(screen->monitor->config))->mon_option_lst;
+ if ((option = xf86findOption(options, Rotate)) != NULL) {
+ if (option->opt_val != NULL)
+ rotate = strcasecmp(option->opt_val, _CW) == 0 ? CW :
+ strcasecmp(option->opt_val, _CCW) == 0 ? CCW : 0;
+ xf86removeOption(&((XF86ConfMonitorPtr)(screen->monitor->config))
+ ->mon_option_lst, Rotate);
+ }
+ }
+ if (screen->card != NULL) {
+ options = ((XF86ConfDevicePtr)(screen->card->config))->dev_option_lst;
+ if ((option = xf86findOption(options, Rotate)) != NULL) {
+ if (option->opt_val != NULL)
+ rotate += strcasecmp(option->opt_val, _CW) == 0 ? CW :
+ strcasecmp(option->opt_val, _CCW) == 0 ? CCW : 0;
+ xf86removeOption(&((XF86ConfDevicePtr)(screen->card->config))
+ ->dev_option_lst, Rotate);
+ }
+ }
+
+ options = screen->screen->scrn_option_lst;
+ if ((option = xf86findOption(options, Rotate)) != NULL) {
+ if (option->opt_val != NULL)
+ rotate += strcasecmp(option->opt_val, _CW) == 0 ? CW :
+ strcasecmp(option->opt_val, _CCW) == 0 ? CCW : 0;
+ xf86removeOption(&screen->screen->scrn_option_lst, Rotate);
+ }
+
+ rotate = rotate > 0 ? CW : rotate < 0 ? CCW : 0;
+ if (rotate)
+ screen->screen->scrn_option_lst =
+ xf86addNewOption(screen->screen->scrn_option_lst,
+ XtNewString(Rotate),
+ XtNewString(rotate > 0 ? _CW : _CCW));
+ screen->rotate = rotate;
+}
+
+void
+CreateScreenWidget(xf86cfgScreen *screen)
+{
+ Widget w = XtCreateWidget("screen", simpleWidgetClass,
+ XtParent(computer.cpu), NULL, 0);
+
+ SetScreenRotate(screen);
+ XtRealizeWidget(w);
+ screen->widget = w;
+ screen->column = screen->row = -1;
+
+ ReshapeScreenWidget(screen);
+}
+
+void
+ReshapeScreenWidget(xf86cfgScreen *screen)
+{
+ Pixmap pixmap;
+ XGCValues values;
+ GC gc;
+ int x = 0, y = 0, width = screen->rect.width, height = screen->rect.height;
+ Widget w = screen->widget;
+
+ if (screen->state == USED && screen->row >= 0) {
+ if (screen->column == 0)
+ x = w->core.width - width;
+ else if (screen->column == columns - 1)
+ x = w->core.width - mon_widths[screen->column];
+ else
+ x = (w->core.width - mon_widths[screen->column]) +
+ ((mon_widths[screen->column] - width) >> 1);
+
+ if (screen->row == 0)
+ y = w->core.height - height;
+ else if (screen->row == rows - 1)
+ y = w->core.height - mon_heights[screen->row];
+ else
+ y = (w->core.height - mon_heights[screen->row]) +
+ ((mon_heights[screen->row] - height) >> 1);
+ }
+ else if (screen->rect.width == 0) {
+ width = w->core.width;
+ height = w->core.height;
+ }
+
+ screen->rect.x = x;
+ screen->rect.y = y;
+ screen->rect.width = width;
+ screen->rect.height = height;
+ pixmap = XCreatePixmap(XtDisplay(w), XtWindow(w),
+ w->core.width, w->core.height, 1);
+ values.foreground = 0;
+ values.background = 1;
+ gc = XCreateGC(XtDisplay(w), pixmap, GCForeground | GCBackground, &values);
+ XFillRectangle(XtDisplay(w), pixmap, gc, 0, 0, w->core.width, w->core.height);
+ XSetForeground(XtDisplay(w), gc, 1);
+
+ DrawScreenMask(XtDisplay(w), pixmap, gc, x, y, x + width, y + height,
+ screen->rotate);
+ XShapeCombineMask(XtDisplay(w), XtWindow(w), ShapeBounding,
+ 0, 0, pixmap, ShapeSet);
+
+ /* Do not call XtSetValues, to avoid all extra code for caching pixmaps */
+ XFreePixmap(XtDisplay(w), pixmap);
+ if (XtIsRealized(w)) {
+ pixmap = XCreatePixmap(XtDisplay(w), XtWindow(w),
+ w->core.width, w->core.height,
+ DefaultDepthOfScreen(XtScreen(w)));
+ DrawScreen(XtDisplay(w), pixmap, x, y, x + width, y + height,
+ screen->state == USED ? True : False, screen->rotate);
+ XSetWindowBackgroundPixmap(XtDisplay(w), XtWindow(w), pixmap);
+ XClearWindow(XtDisplay(w), XtWindow(w));
+ XFreePixmap(XtDisplay(w), pixmap);
+ }
+ XFreeGC(XtDisplay(w), gc);
+}
+
+void
+AddScreen(xf86cfgDevice *mon, xf86cfgDevice *dev)
+{
+ int nscreens = 0;
+ char screen_name[48];
+ XF86ConfScreenPtr screen = XF86Config->conf_screen_lst;
+ XF86ConfAdjacencyPtr adj;
+
+ while (screen != NULL) {
+ ++nscreens;
+ screen = (XF86ConfScreenPtr)(screen->list.next);
+ }
+ do {
+ XmuSnprintf(screen_name, sizeof(screen_name), "Screen%d",
+ nscreens);
+ ++nscreens;
+ } while (xf86findScreen(screen_name,
+ XF86Config->conf_screen_lst) != NULL);
+
+ screen = (XF86ConfScreenPtr)XtCalloc(1, sizeof(XF86ConfScreenRec));
+ screen->scrn_identifier = XtNewString(screen_name);
+ screen->scrn_device_str = XtNewString(((XF86ConfDevicePtr)(dev->config))->dev_identifier);
+ screen->scrn_device = (XF86ConfDevicePtr)(dev->config);
+ screen->scrn_monitor_str = XtNewString(((XF86ConfMonitorPtr)(mon->config))->mon_identifier);
+ screen->scrn_monitor = (XF86ConfMonitorPtr)(mon->config);
+ XF86Config->conf_screen_lst =
+ xf86addScreen(XF86Config->conf_screen_lst, screen);
+
+ adj = (XF86ConfAdjacencyPtr)XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
+ adj->adj_screen = screen;
+ adj->adj_screen_str = XtNewString(screen_name);
+ if (computer.layout == NULL)
+ computer.layout = XF86Config->conf_layout_lst = (XF86ConfLayoutPtr)
+ XtCalloc(1, sizeof(XF86ConfLayoutRec));
+ computer.layout->lay_adjacency_lst = (XF86ConfAdjacencyPtr)
+ xf86addListItem((GenericListPtr)computer.layout->lay_adjacency_lst,
+ (GenericListPtr)adj);
+
+ computer.screens = (xf86cfgScreen**)
+ XtRealloc((XtPointer)computer.screens, sizeof(xf86cfgScreen*) *
+ (computer.num_screens + 1));
+ computer.screens[computer.num_screens] =
+ (xf86cfgScreen*)XtCalloc(1, sizeof(xf86cfgScreen));
+ computer.screens[computer.num_screens]->screen = screen;
+ computer.screens[computer.num_screens]->card = dev;
+ computer.screens[computer.num_screens]->monitor = mon;
+
+ ++dev->refcount;
+ ++mon->refcount;
+
+ CreateScreenWidget(computer.screens[computer.num_screens]);
+ computer.screens[computer.num_screens]->type = SCREEN;
+ SetTip((xf86cfgDevice*)computer.screens[computer.num_screens]);
+
+ ++computer.num_screens;
+}
+
+void
+RemoveScreen(xf86cfgDevice *mon, xf86cfgDevice *dev)
+{
+ XF86ConfScreenPtr screen = XF86Config->conf_screen_lst;
+ int i;
+
+ mon->state = dev->state = UNUSED;
+ while (screen != NULL) {
+ if ((XtPointer)screen->scrn_monitor == mon->config &&
+ (XtPointer)screen->scrn_device == dev->config)
+ break;
+
+ screen = (XF86ConfScreenPtr)(screen->list.next);
+ }
+ --mon->refcount;
+ --dev->refcount;
+
+ for (i = 0; i < computer.num_screens; i++) {
+ if (computer.screens[i]->screen == screen) {
+ XtDestroyWidget(computer.screens[i]->widget);
+ if (i < --computer.num_screens)
+ memmove(&computer.screens[i], &computer.screens[i + 1],
+ (computer.num_screens - i) * sizeof(xf86cfgScreen*));
+ break;
+ }
+ }
+
+ xf86removeScreen(XF86Config, screen);
+}
+
+void
+ChangeScreen(XF86ConfMonitorPtr mon, XF86ConfMonitorPtr oldmon,
+ XF86ConfDevicePtr dev, XF86ConfDevicePtr olddev)
+{
+ int ioldm, im, ioldc, ic;
+
+ if (mon == oldmon && dev == olddev)
+ return;
+
+ if (mon != NULL) {
+ for (im = 0; im < computer.num_devices; im++)
+ if (computer.devices[im]->config == (XtPointer)mon)
+ break;
+ }
+ else
+ im = -1;
+ if (oldmon != NULL) {
+ for (ioldm = 0; ioldm < computer.num_devices; ioldm++)
+ if (computer.devices[ioldm]->config == (XtPointer)oldmon)
+ break;
+ }
+ else
+ ioldm = -1;
+
+ if (dev != NULL) {
+ for (ic = 0; ic < computer.num_devices; ic++)
+ if (computer.devices[ic]->config == (XtPointer)dev)
+ break;
+ }
+ else
+ ic = -1;
+ if (olddev != NULL) {
+ for (ioldc = 0; ioldc < computer.num_devices; ioldc++)
+ if (computer.devices[ioldc]->config == (XtPointer)olddev)
+ break;
+ }
+ else
+ ioldc = -1;
+
+ if (ioldm >= 0 && ioldc >= 0) {
+ RemoveScreen(computer.devices[ioldm], computer.devices[ioldc]);
+ computer.devices[ioldm]->state = UNUSED;
+/* computer.devices[ioldc]->state = UNUSED;*/
+ }
+
+ if (im >= 0 && ic >= 0) {
+ AddScreen(computer.devices[im], computer.devices[ic]);
+ computer.devices[im]->state = USED;
+/* computer.devices[ic]->state = USED;*/
+ }
+}
+
+/*
+
++------------------------------------------------+
+| |
+| +------------------------------------------+ |
+| | | |
+| | | |
+| | | |
+| | | |
+| | | |
+| | | |
+| | | |
+| | | |
+| | | |
+| | | |
+| | | |
+| | | |
+| | | |
+| | | |
+| +------------------------------------------+ |
+| |
++------------------------------------------------+
+ | |
+ +-------+ +-------+
+ | |
+ +----------------------------------------+
+
+ */
+static double oxs = 0.0, oys = 0.0, oxe = 100.0, oye = 70.0;
+static double ixs = 7.0, iys = 7.0, ixe = 93.0, iye = 63.0;
+static double lin[] = { 25.0, 70.0, 25.0, 75.0, 5.0, 75.0, 5.0, 80.0,
+ 95.0, 80.0, 95.0, 75.0, 75.0, 75.0, 75.0, 70.0 };
+
+void
+DrawScreen(Display *dpy, Drawable win, int xs, int ys, int xe, int ye,
+ Bool active, int rotate)
+{
+ double xfact, yfact;
+ XPoint points[(sizeof(lin) / sizeof(lin[0])) >> 1];
+ int i;
+ static GC gray0, gray1, gray2, black, red;
+
+ if (black == NULL) {
+ XColor color, exact;
+ XGCValues values;
+
+ XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap, "gray95",
+ &color, &exact);
+ values.foreground = color.pixel;
+ gray0 = XCreateGC(XtDisplay(toplevel), win, GCForeground, &values);
+ XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap, "gray75",
+ &color, &exact);
+ values.foreground = color.pixel;
+ gray1 = XCreateGC(XtDisplay(toplevel), win, GCForeground, &values);
+
+ XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap, "gray60",
+ &color, &exact);
+ values.foreground = color.pixel;
+ gray2 = XCreateGC(XtDisplay(toplevel), win, GCForeground, &values);
+
+ XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap, "gray20",
+ &color, &exact);
+ values.foreground = color.pixel;
+ black = XCreateGC(XtDisplay(toplevel), win, GCForeground, &values);
+
+ XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap, "red",
+ &color, &exact);
+ values.foreground = color.pixel;
+ values.line_width = 4;
+ values.cap_style = CapButt;
+ red = XCreateGC(XtDisplay(toplevel), win,
+ GCForeground | GCLineWidth | GCCapStyle, &values);
+ }
+
+ if (rotate) {
+ xfact = (xe - xs) / 80.0;
+ yfact = (ye - ys) / 100.0;
+ if (rotate == CW) {
+ /* outer rectangle */
+ XFillRectangle(dpy, win, gray1,
+ oxs * xfact + xs + .5,
+ oys * yfact + ys + .5,
+ (oye - oys) * xfact + .5,
+ (oxe - oxs) * yfact + .5);
+ XDrawLine(dpy, win, gray2,
+ xs, ye - 1,
+ 70 * xfact + xs - 1 + .5, ye - 1);
+ XDrawLine(dpy, win, gray2,
+ 70 * xfact + xs - 1 + .5, ye - 1,
+ 70 * xfact + xs - 1 + .5, ys);
+ /* inner rectangle */
+ XFillRectangle(dpy, win, black,
+ ixs * xfact + xs + .5,
+ iys * yfact + ys + .5,
+ (iye - iys) * xfact + .5,
+ (ixe - ixs) * yfact + .5);
+ for (i = 0; i < sizeof(points) / sizeof(points[0]); i++) {
+ points[i].x = lin[(i<<1) + 1] * xfact + xs + .5;
+ points[i].y = lin[(i<<1)] * yfact + ys + .5;
+ }
+ XFillPolygon(dpy, win, gray2, points, i, Convex, CoordModeOrigin);
+ XDrawLine(dpy, win, gray0,
+ (oxe - 10) * xfact + xs + .5, oys * yfact + ys + .5,
+ xs, oys * yfact + ys + .5);
+ XDrawLine(dpy, win, gray0,
+ xs, ys,
+ xs, xe);
+ XDrawLine(dpy, win, black,
+ lin[7] * xfact + xs - 1 + .5, lin[6] * yfact + ys + .5,
+ lin[9] * xfact + xs - 1 + .5, lin[8] * yfact + ys - 1 + .5);
+ XDrawLine(dpy, win, black,
+ lin[9] * xfact + xs - 1 + .5, lin[8] * yfact + ys - 1 + .5,
+ lin[11] * xfact + xs + .5, lin[10] * yfact + ys - 1 + .5);
+ XDrawLine(dpy, win, black,
+ lin[13] * xfact + xs + .5, lin[12] * yfact + ys - 1 + .5,
+ lin[15] * xfact + xs + .5, lin[14] * yfact + ys - 1 + .5);
+
+ if (!active) {
+ XDrawLine(dpy, win, red,
+ iys * xfact, ixs * yfact, iye * xfact, ixe * yfact);
+ XDrawLine(dpy, win, red,
+ iye * xfact, ixs * yfact, iys * xfact, ixe * yfact);
+ }
+ }
+ else if (rotate == CCW) {
+ /* outer rectangle */
+ XFillRectangle(dpy, win, gray1,
+ 10 * xfact + xs + .5,
+ oys * yfact + ys + .5,
+ (oye - oys) * xfact + .5,
+ (oxe - oxs) * yfact + .5);
+
+ XDrawLine(dpy, win, gray2,
+ 10 * xfact + xs + .5, ye - 1,
+ oxe * xfact + xs - 1 + .5, ye - 1);
+ XDrawLine(dpy, win, gray2,
+ xe - 1, ye - 1,
+ xe - 1, ys);
+ /* inner rectangle */
+ XFillRectangle(dpy, win, black,
+ (ixs + 10) * xfact + xs + .5,
+ iys * yfact + ys + .5,
+ (iye - iys) * xfact + .5,
+ (ixe - ixs) * yfact + .5);
+ for (i = 0; i < sizeof(points) / sizeof(points[0]); i++) {
+ points[i].x = (-lin[(i<<1) + 1] + 80.0) * xfact + xs + .5;
+ points[i].y = lin[(i<<1)] * yfact + ys + .5;
+ }
+ XFillPolygon(dpy, win, gray2, points, i, Convex, CoordModeOrigin);
+ XDrawLine(dpy, win, gray0,
+ oxe * xfact + xs + .5, oys * yfact + ys + .5,
+ (oxs - 10) * xfact + xs + .5, oys * yfact + ys + .5);
+ XDrawLine(dpy, win, gray0,
+ (oxs + 10) * xfact + xs + .5, ys,
+ (oxs + 10) * xfact + xs + .5, xe);
+
+ XDrawLine(dpy, win, black,
+ xs, lin[8] * yfact - 1 + ys + .5,
+ 4 * xfact + xs + .5, lin[8] * yfact - 1 + ys + .5);
+ XDrawLine(dpy, win, black,
+ 4 * xfact + xs, lin[8] * yfact - 1 + ys + .5,
+ 4 * xfact + xs, lin[3] * yfact - 1 + ys + .5);
+ XDrawLine(dpy, win, black,
+ 4 * xfact + xs + .5, lin[3] * yfact - 1 + ys + .5,
+ 10 * xfact + xs + .5 - 1, lin[3] * yfact - 1 + ys + .5);
+ XDrawLine(dpy, win, black,
+ 4 * xfact + xs, lin[0] * yfact - 1 + ys + .5,
+ 4 * xfact + xs, lin[4] * yfact - 1 + ys + .5);
+
+ if (!active) {
+ XDrawLine(dpy, win, red,
+ (iys + 10) * xfact, ixs * yfact,
+ (iye + 10) * xfact, ixe * yfact);
+ XDrawLine(dpy, win, red,
+ (iye + 10) * xfact, ixs * yfact,
+ (iys + 10) * xfact, ixe * yfact);
+ }
+ }
+ }
+ else {
+ xfact = (xe - xs) / 100.0;
+ yfact = (ye - ys) / 80.0;
+
+ /* outer rectangle */
+ XFillRectangle(dpy, win, gray1,
+ oxs * xfact + xs + .5,
+ oys * yfact + ys + .5,
+ (oxe - oxs) * xfact + .5,
+ (oye - oys) * yfact + .5);
+
+ XDrawLine(dpy, win, gray2,
+ oxs * xfact + xs + .5, oye * yfact + ys - 1 + .5,
+ oxe * xfact + xs - 1 + .5, oye * yfact + ys - 1 + .5);
+ XDrawLine(dpy, win, gray2,
+ oxe * xfact + xs - 1 + .5, oys * yfact + ys + .5,
+ oxe * xfact + xs - 1 + .5, oye * yfact + ys - 1 + .5);
+
+ /* inner rectangle */
+ XFillRectangle(dpy, win, black,
+ ixs * xfact + xs + .5,
+ iys * yfact + ys + .5,
+ (ixe - ixs) * xfact + .5,
+ (iye - iys) * yfact + .5);
+
+ for (i = 0; i < sizeof(points) / sizeof(points[0]); i++) {
+ points[i].x = lin[i<<1] * xfact + xs + .5;
+ points[i].y = lin[(i<<1) + 1] * yfact + ys + .5;
+ }
+
+ XFillPolygon(dpy, win, gray2, points, i, Convex, CoordModeOrigin);
+
+ XDrawLine(dpy, win, black,
+ lin[6] * xfact + xs + .5, lin[7] * yfact + ys - 1 + .5,
+ lin[8] * xfact + xs - 1 + .5, lin[9] * yfact + ys - 1 + .5);
+ XDrawLine(dpy, win, black,
+ lin[8] * xfact + xs - 1 + .5, lin[9] * yfact + ys - 1 + .5,
+ lin[10] * xfact + xs - 1 + .5, lin[11] * yfact + ys + .5);
+ XDrawLine(dpy, win, black,
+ lin[12] * xfact + xs - 1 + .5, lin[13] * yfact + ys + .5,
+ lin[14] * xfact + xs - 1 + .5, lin[15] * yfact + ys + .5);
+
+ XDrawLine(dpy, win, gray0,
+ oxe * xfact + xs + .5, oys * yfact + ys + .5,
+ oxs * xfact + xs + .5, oys * yfact + ys + .5);
+ XDrawLine(dpy, win, gray0,
+ oxs * xfact + xs + .5, oys * yfact + ys + .5,
+ oxs * xfact + xs + .5, lin[1] * yfact + ys + .5);
+
+ if (!active) {
+ XDrawLine(dpy, win, red,
+ ixs * xfact, iys * yfact, ixe * xfact, iye * yfact);
+ XDrawLine(dpy, win, red,
+ ixe * xfact, iys * yfact, ixs * xfact, iye * yfact);
+ }
+ }
+}
+
+void
+DrawScreenMask(Display *dpy, Drawable win, GC gc, int xs, int ys, int xe, int ye,
+ int rotate)
+{
+ double xfact, yfact;
+ XPoint points[(sizeof(lin) / sizeof(lin[0])) >> 1];
+ int i = 0, x = 0, y = 0, width, height;
+
+ if (rotate) {
+ xfact = (xe - xs) / 80.0;
+ yfact = (ye - ys) / 100.0;
+ width = (oye - oys) * xfact + .5;
+ height = (oxe - oxs) * yfact + .5;
+ if (rotate == CW) {
+ x = oxs * xfact + xs + .5;
+ y = oys * yfact + ys + .5;
+ for (i = 0; i < sizeof(points) / sizeof(points[0]); i++) {
+ points[i].x = lin[(i<<1) + 1] * xfact + xs + .5;
+ points[i].y = lin[(i<<1)] * yfact + ys + .5;
+ }
+ }
+ else if (rotate == CCW) {
+ x = 10 * xfact + xs + .5;
+ y = oys * yfact + ys + .5;
+ for (i = 0; i < sizeof(points) / sizeof(points[0]); i++) {
+ points[i].x = (-lin[(i<<1) + 1] + 80.0) * xfact + xs + .5;
+ points[i].y = lin[(i<<1)] * yfact + ys + .5;
+ }
+ }
+ }
+ else {
+ xfact = (xe - xs) / 100.0;
+ yfact = (ye - ys) / 80.0;
+ x = oxs * xfact + xs + .5;
+ y = oys * yfact + ys + .5;
+ width = (oxe - oxs) * xfact + .5;
+ height = (oye - oys) * yfact + .5;
+ for (i = 0; i < sizeof(points) / sizeof(points[0]); i++) {
+ points[i].x = lin[(i<<1)] * xfact + xs + .5;
+ points[i].y = lin[(i<<1) + 1] * yfact + ys + .5;
+ }
+ }
+
+ /* rectangle */
+ XFillRectangle(dpy, win, gc, x, y, width, height);
+
+
+ XFillPolygon(dpy, win, gc, points, i, Convex, CoordModeOrigin);
+}
+
+void
+AdjustScreenUI(void)
+{
+ XF86ConfLayoutPtr lay = computer.layout;
+ XF86ConfAdjacencyPtr adj;
+ int i, dx, dy, x, y, w, h, base = -1;
+ double xf, yf;
+
+ if (lay == NULL)
+ return;
+
+ adj = lay->lay_adjacency_lst;
+
+#define USED1 -USED
+
+ XtFree((XtPointer)mon_widths);
+ XtFree((XtPointer)mon_heights);
+ mon_widths = (int*)XtCalloc(1, sizeof(int) * columns);
+ mon_heights = (int*)XtCalloc(1, sizeof(int) * rows);
+
+ mon_width = mon_height = 0;
+ for (i = 0; i < computer.num_screens; i++) {
+ if (base == -1 && computer.screens[i]->state == USED)
+ base = i;
+ if (computer.screens[i]->screen->scrn_monitor->mon_width > mon_width)
+ mon_width = computer.screens[i]->screen->scrn_monitor->mon_width;
+ if (computer.screens[i]->screen->scrn_monitor->mon_height > mon_height)
+ mon_height = computer.screens[i]->screen->scrn_monitor->mon_height;
+ }
+ if (base < 0) {
+ for (i = 0; i < computer.num_screens; i++)
+ ReshapeScreenWidget(computer.screens[i]);
+ return;
+ }
+
+ if (mon_width == 0) {
+ mon_width = 10;
+ mon_height = 8;
+ }
+
+ XtUnmapWidget(work);
+
+ while (adj) {
+ xf86cfgScreen *scr = NULL,
+ *topscr = NULL, *botscr = NULL, *lefscr = NULL, *rigscr = NULL;
+
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->screen == adj->adj_screen)
+ break;
+ if (i < computer.num_screens)
+ scr = computer.screens[i];
+
+ if (adj->adj_top != NULL) {
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->screen == adj->adj_top)
+ break;
+ if (i < computer.num_screens)
+ topscr = computer.screens[i];
+ }
+
+ if (adj->adj_bottom != NULL) {
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->screen == adj->adj_bottom)
+ break;
+ if (i < computer.num_screens)
+ botscr = computer.screens[i];
+ }
+
+ if (adj->adj_left != NULL) {
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->screen == adj->adj_left)
+ break;
+ if (i < computer.num_screens)
+ lefscr = computer.screens[i];
+ }
+
+ if (adj->adj_right != NULL) {
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->screen == adj->adj_right)
+ break;
+ if (i < computer.num_screens)
+ rigscr = computer.screens[i];
+ }
+
+ if (lefscr == NULL && rigscr == NULL && topscr == NULL && lefscr == NULL) {
+ XF86ConfScreenPtr s;
+
+ if (adj->adj_where >= CONF_ADJ_RIGHTOF < adj->adj_where <= CONF_ADJ_BELOW) {
+ s = xf86findScreen(adj->adj_refscreen, XF86Config->conf_screen_lst);
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->screen == s)
+ break;
+ if (i < computer.num_screens) {
+ switch (adj->adj_where) {
+ case CONF_ADJ_RIGHTOF:
+ lefscr = computer.screens[i];
+ break;
+ case CONF_ADJ_LEFTOF:
+ rigscr = computer.screens[i];
+ break;
+ case CONF_ADJ_ABOVE:
+ botscr = computer.screens[i];
+ break;
+ case CONF_ADJ_BELOW:
+ topscr = computer.screens[i];
+ break;
+ }
+ }
+ }
+ }
+
+ XtMoveWidget(scr->widget, 0, 0);
+ scr->state = USED1;
+ if (lefscr != NULL) {
+ if (lefscr->state == USED1)
+ XtMoveWidget(scr->widget,
+ lefscr->widget->core.x + lefscr->widget->core.width,
+ lefscr->widget->core.y);
+ else
+ XtMoveWidget(lefscr->widget,
+ -(int)(lefscr->widget->core.width),
+ scr->widget->core.y);
+ }
+
+ if (rigscr != NULL) {
+ if (rigscr->state == USED1) {
+ dx = rigscr->widget->core.x - scr->widget->core.width - scr->widget->core.x;
+ dy = rigscr->widget->core.y - scr->widget->core.y;
+
+ XtMoveWidget(scr->widget, scr->widget->core.x + dx,
+ scr->widget->core.y + dy);
+ if (lefscr != NULL && lefscr->state != USED1)
+ XtMoveWidget(lefscr->widget, lefscr->widget->core.x + dx,
+ lefscr->widget->core.y + dy);
+ }
+ else
+ XtMoveWidget(rigscr->widget, scr->widget->core.width,
+ scr->widget->core.y);
+ }
+
+ if (topscr != NULL) {
+ if (topscr->state == USED1) {
+ dx = topscr->widget->core.x - scr->widget->core.x;
+ dy = topscr->widget->core.y + topscr->widget->core.height -
+ scr->widget->core.y;
+
+ XtMoveWidget(scr->widget, scr->widget->core.x + dx,
+ scr->widget->core.y + dy);
+ if (lefscr != NULL && lefscr->state != USED1)
+ XtMoveWidget(lefscr->widget, lefscr->widget->core.x + dx,
+ lefscr->widget->core.y + dy);
+ if (rigscr != NULL && rigscr->state != USED1)
+ XtMoveWidget(rigscr->widget, rigscr->widget->core.x + dx,
+ rigscr->widget->core.y + dy);
+ }
+ else
+ XtMoveWidget(topscr->widget, scr->widget->core.x,
+ scr->widget->core.y - topscr->widget->core.height);
+ }
+
+ if (botscr != NULL) {
+ if (botscr->state == USED1) {
+ dx = botscr->widget->core.x - scr->widget->core.x;
+ dy = botscr->widget->core.y - scr->widget->core.height - scr->widget->core.y;
+
+ XtMoveWidget(scr->widget, scr->widget->core.x + dx,
+ scr->widget->core.y + dy);
+ if (lefscr != NULL && lefscr->state != USED1)
+ XtMoveWidget(lefscr->widget, lefscr->widget->core.x + dx,
+ lefscr->widget->core.y + dy);
+ if (rigscr != NULL && rigscr->state != USED1)
+ XtMoveWidget(rigscr->widget, rigscr->widget->core.x + dx,
+ rigscr->widget->core.y + dy);
+ if (botscr != NULL && botscr->state != USED1)
+ XtMoveWidget(botscr->widget, botscr->widget->core.x + dx,
+ botscr->widget->core.y + dy);
+ }
+ else
+ XtMoveWidget(botscr->widget, scr->widget->core.x,
+ scr->widget->core.y + scr->widget->core.height);
+ }
+
+ adj = (XF86ConfAdjacencyPtr)(adj->list.next);
+ }
+
+ for (i = 0; i < computer.num_screens; i++)
+ if (computer.screens[i]->state == USED1)
+ computer.screens[i]->state = USED;
+ else
+ XLowerWindow(XtDisplay(computer.screens[i]->widget),
+ XtWindow(computer.screens[i]->widget));
+
+ w = work->core.width / (columns + 1) - 5;
+ h = work->core.height / (rows + 1) - 5;
+
+ if (w > h)
+ w = h;
+ else
+ h = w;
+
+ dx = (work->core.width - (columns * w)) >> 1;
+ dy = (work->core.height - (rows * h)) >> 1;
+
+ xf = (double)w / (double)computer.screens[0]->widget->core.width;
+ yf = (double)h / (double)computer.screens[0]->widget->core.height;
+
+ for (i = 0; i < computer.num_screens; i++) {
+ Widget z = computer.screens[i]->widget;
+
+ if (computer.screens[i]->state == USED)
+ XtConfigureWidget(z, z->core.x * xf + dx,
+ z->core.y * yf + dy, w, h, 0);
+ else
+ XtConfigureWidget(z, z->core.x, z->core.y, w, h, 0);
+ }
+
+ if (computer.screens[base]->row >= 0) {
+ double xf, yf;
+ int width, height;
+
+ for (i = 0; i < computer.num_screens; i++) {
+ width = computer.screens[i]->screen->scrn_monitor->mon_width;
+ height = computer.screens[i]->screen->scrn_monitor->mon_height;
+ if (width <= 0) {
+ width = mon_width;
+ height = mon_height;
+ }
+
+ if (computer.screens[i]->rotate) {
+ xf = (double)width / (double)mon_width * 8. / 10.;
+ yf = (double)height / (double)mon_height;
+ }
+ else {
+ xf = (double)width / (double)mon_width;
+ yf = (double)height / (double)mon_height * 8. / 10.;
+ }
+ width = computer.screens[i]->widget->core.width * xf;
+ height = computer.screens[i]->widget->core.height * yf;
+ if (computer.screens[i]->state == USED) {
+ if (mon_widths[computer.screens[i]->column] < width)
+ mon_widths[computer.screens[i]->column] = width;
+ if (mon_heights[computer.screens[i]->row] < height)
+ mon_heights[computer.screens[i]->row] = height;
+ }
+
+ /* do it here to avoid recalculation */
+ computer.screens[i]->rect.width = width;
+ computer.screens[i]->rect.height = height;
+ }
+ }
+
+ for (i = 0; i < computer.num_screens; i++)
+ ReshapeScreenWidget(computer.screens[i]);
+
+ /* do a new pass, to avoid gaps if the monitors have different
+ * sizes.
+ */
+ if (computer.screens[base]->row >= 0) {
+ x = computer.screens[base]->widget->core.x;
+ y = computer.screens[base]->widget->core.y;
+
+ /* screens representations are already ordered */
+ for (i = base; i < computer.num_screens; i++) {
+ if (computer.screens[i]->state == UNUSED)
+ continue;
+ if (computer.screens[i]->column != 0)
+ x += mon_widths[computer.screens[i]->column];
+ else {
+ x = computer.screens[base]->widget->core.x;
+ if (i != base)
+ y += mon_heights[computer.screens[i]->row];
+ }
+ XtMoveWidget(computer.screens[i]->widget, x, y);
+ }
+ }
+ XtMapWidget(work);
+}
+
+static int
+qcmp_screen(_Xconst void *a, _Xconst void *b)
+{
+ xf86cfgScreen *s1, *s2;
+
+ s1 = *(xf86cfgScreen**)a;
+ s2 = *(xf86cfgScreen**)b;
+
+ if (s1->widget->core.x > s2->widget->core.x) {
+ if (s2->widget->core.y >=
+ s1->widget->core.y + (s1->widget->core.height >> 1))
+ return (-1);
+ return (1);
+ }
+ else {
+ if (s1->widget->core.y >=
+ s2->widget->core.y + (s2->widget->core.height >> 1))
+ return (1);
+ return (-1);
+ }
+ /*NOTREACHED*/
+}
+
+void
+UpdateScreenUI(void)
+{
+ XF86ConfLayoutPtr lay = computer.layout;
+ XF86ConfAdjacencyPtr adj, prev, left, base;
+ int i, p, cols, scrno;
+
+ if (lay == NULL)
+ return;
+
+ rows = columns = cols = 1;
+
+ qsort(computer.screens, computer.num_screens, sizeof(xf86cfgScreen*),
+ qcmp_screen);
+
+ adj = prev = left = base = NULL;
+ for (i = p = scrno = 0; i < computer.num_screens; i++) {
+ XF86ConfScreenPtr scr = computer.screens[i]->screen;
+
+ if (computer.screens[i]->state == UNUSED)
+ continue;
+
+ adj = (XF86ConfAdjacencyPtr)XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
+ adj->adj_scrnum = scrno++;
+ adj->adj_screen = scr;
+ adj->adj_screen_str = XtNewString(scr->scrn_identifier);
+ if (base == NULL) {
+ base = left = adj;
+ computer.screens[i]->row = computer.screens[i]->column = 0;
+ }
+ else {
+ int dy = computer.screens[i]->widget->core.y -
+ computer.screens[p]->widget->core.y;
+
+ prev->list.next = adj;
+ if (dy > (computer.screens[i]->widget->core.height >> 1)) {
+ adj->adj_where = CONF_ADJ_BELOW;
+ adj->adj_refscreen = XtNewString(left->adj_screen_str);
+ left = adj;
+ computer.screens[i]->row = rows;
+ computer.screens[i]->column = 0;
+ cols = 1;
+ ++rows;
+ }
+ else {
+ computer.screens[i]->row = rows - 1;
+ computer.screens[i]->column = cols;
+ adj->adj_where = CONF_ADJ_RIGHTOF;
+ if (++cols > columns)
+ columns = cols;
+ adj->adj_refscreen = XtNewString(prev->adj_screen_str);
+ }
+ }
+ prev = adj;
+ p = i;
+ }
+
+ adj = lay->lay_adjacency_lst;
+
+ while (adj != NULL) {
+ prev = adj;
+ adj = (XF86ConfAdjacencyPtr)(adj->list.next);
+ XtFree(prev->adj_screen_str);
+ XtFree(prev->adj_right_str);
+ XtFree(prev->adj_left_str);
+ XtFree(prev->adj_top_str);
+ XtFree(prev->adj_bottom_str);
+ XtFree(prev->adj_refscreen);
+ XtFree((char*)prev);
+ }
+
+ lay->lay_adjacency_lst = base;
+}
diff --git a/hw/xfree86/utils/xorgcfg/screen.h b/hw/xfree86/utils/xorgcfg/screen.h
new file mode 100644
index 000000000..7c3e2c75f
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/screen.h
@@ -0,0 +1,52 @@
+/*
+ * 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/screen.h,v 1.3 2000/12/01 18:31:07 paulo Exp $
+ */
+
+#include "xf86config.h"
+#include "config.h"
+
+#ifndef _xf86cfg_screen_h
+#define _xf86cfg_screen_h
+
+/*
+ * Prototypes
+ */
+void AddScreen(xf86cfgDevice*, xf86cfgDevice*);
+void RemoveScreen(xf86cfgDevice*, xf86cfgDevice*);
+
+void DrawScreen(Display*, Drawable, int, int, int, int, Bool, int);
+void DrawScreenMask(Display*, Drawable, GC, int, int, int, int, int);
+void CreateScreenWidget(xf86cfgScreen*);
+void SetScreenRotate(xf86cfgScreen*);
+
+void AdjustScreenUI(void);
+void UpdateScreenUI(void);
+
+#endif /* _xf86cfg_screen_h */
diff --git a/hw/xfree86/utils/xorgcfg/shorter.xbm b/hw/xfree86/utils/xorgcfg/shorter.xbm
new file mode 100644
index 000000000..878f219d4
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/shorter.xbm
@@ -0,0 +1,8 @@
+#define shorter_width 19
+#define shorter_height 19
+static unsigned char shorter_bits[] = {
+ 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0xfc, 0xff, 0x01,
+ 0xf8, 0xff, 0x00, 0xf0, 0x7f, 0x00, 0xe0, 0x3f, 0x00, 0xc0, 0x1f, 0x00,
+ 0x80, 0x0f, 0x00, 0x00, 0x07, 0x00, 0x80, 0x0f, 0x00, 0xc0, 0x1f, 0x00,
+ 0xe0, 0x3f, 0x00, 0xf0, 0x7f, 0x00, 0xf8, 0xff, 0x00, 0xfc, 0xff, 0x01,
+ 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00};
diff --git a/hw/xfree86/utils/xorgcfg/startx.c b/hw/xfree86/utils/xorgcfg/startx.c
new file mode 100644
index 000000000..23b0ecf5a
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/startx.c
@@ -0,0 +1,150 @@
+/*
+ * 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/startx.c,v 1.8 2002/10/19 20:04:21 herrb Exp $
+ */
+
+#include "config.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+
+/*
+ * Initialization
+ */
+static int xpid;
+Display *DPY;
+
+/*
+ * Implementation
+ */
+Bool
+startx(void)
+{
+ int timeout = 8;
+
+ if (getenv("DISPLAY") != NULL)
+ /* already running Xserver */
+ return (False);
+
+ if (XF86Config_path == NULL) {
+ char *home, filename[PATH_MAX];
+ char commandline[PATH_MAX * 4];
+ int c_pos;
+ int len;
+ /*
+ * The name of the 4.0 binary is XFree86. X might also
+ * be the name of the 3.3 binary. Therefore don't change
+ * name to 'X'.
+ */
+ if (XFree86_path)
+ c_pos = XmuSnprintf(commandline, sizeof(commandline),
+ "%s/XFree86 :8 -configure ",XFree86_path);
+ else
+ c_pos = XmuSnprintf(commandline, sizeof(commandline),
+ "%s/bin/XFree86 :8 -configure ", XFree86Dir);
+ if (XF86Module_path && ((len = sizeof(commandline) - c_pos) > 0))
+ c_pos += XmuSnprintf(commandline + c_pos,len,
+ " -modulepath %s",XF86Module_path);
+ if (XF86Font_path && ((len = sizeof(commandline) - c_pos) > 0))
+ c_pos += XmuSnprintf(commandline + c_pos,len,
+ " -fontpath %s",XF86Font_path);
+ if (XF86RGB_path && ((len = sizeof(commandline) - c_pos) > 0))
+ c_pos += XmuSnprintf(commandline + c_pos,len,
+ " -rgbpath %s",XF86RGB_path);
+
+ if (system(commandline) != 0) {
+ fprintf(stderr, "Failed to run \"X -configure\".\n");
+ exit(1);
+ }
+
+ if ((home = getenv("HOME")) == NULL)
+ home = "/";
+
+#ifndef QNX4
+ XmuSnprintf(filename, sizeof(filename), "%s/XF86Config.new", home);
+#else
+ XmuSnprintf(filename, sizeof(filename), "//%d%s/XF86Config.new",
+ getnid(), home);
+#endif
+
+ /* this memory is never released, even if the value of XF86Config_path is
+ * changed.
+ */
+ XF86Config_path = XtNewString(filename);
+ }
+
+ putenv("DISPLAY=:8");
+
+ switch (xpid = fork()) {
+ case 0: {
+ char path[PATH_MAX];
+ /* Don't change to X! see above */
+ if (XFree86_path)
+ XmuSnprintf(path, sizeof(path), "%s/XFree86", XFree86_path);
+ else
+ XmuSnprintf(path, sizeof(path), "%s/bin/XFree86", XFree86Dir);
+ execl(path, "X", ":8", /*"+xinerama",*/ "+accessx","-allowMouseOpenFail",
+ "-xf86config", XF86Config_path, (void *)NULL);
+ exit(-127);
+ } break;
+ case -1:
+ fprintf(stderr, "Cannot fork.\n");
+ exit(1);
+ break;
+ default:
+ break;
+ }
+
+ while (timeout > 0) {
+ int status;
+
+ sleep(timeout -= 2);
+ if (waitpid(xpid, &status, WNOHANG | WUNTRACED) == xpid)
+ break;
+ else {
+ DPY = XOpenDisplay(NULL);
+ if (DPY != NULL)
+ break;
+ }
+ }
+
+ if (DPY == NULL) {
+ fprintf(stderr, "Cannot connect to X server.\n");
+ exit(1);
+ }
+
+ return (True);
+}
+
+void
+endx(void)
+{
+ if (xpid != 0)
+ kill(xpid, SIGTERM);
+}
diff --git a/hw/xfree86/utils/xorgcfg/stubs.c b/hw/xfree86/utils/xorgcfg/stubs.c
new file mode 100644
index 000000000..5962908d1
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/stubs.c
@@ -0,0 +1,65 @@
+/*
+ * 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/stubs.c,v 1.3 2002/11/09 11:12:53 herrb Exp $
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "stubs.h"
+
+/*
+ * Implementation
+ */
+#if !defined(USE_MODULES)
+/* these are defined in libdummy.a */
+int
+ErrorF(const char *fmt, ...)
+{
+ int retval;
+ va_list ap;
+
+ va_start(ap, fmt);
+ retval = vfprintf(stderr, fmt, ap);
+
+ va_end(ap);
+
+ return (retval);
+}
+
+int
+VErrorF(const char *fmt, va_list ap)
+{
+ int retval;
+
+ retval = vfprintf(stderr, fmt, ap);
+
+ return (retval);
+}
+
+#endif /* !defined(USE_MODULES) */
diff --git a/hw/xfree86/utils/xorgcfg/stubs.h b/hw/xfree86/utils/xorgcfg/stubs.h
new file mode 100644
index 000000000..d554ac17a
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/stubs.h
@@ -0,0 +1,43 @@
+/*
+ * 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/stubs.h,v 1.3 2001/08/01 00:44:57 tsi Exp $
+ */
+
+#ifndef _xf86cfg_stubs_h
+#define _xf86cfg_stubs_h
+
+#include <stdarg.h>
+
+int ErrorF(const char*, ...);
+int VErrorF(const char*, va_list);
+#if defined(USE_MODULES)
+extern int xf86Verbose;
+#endif
+
+#endif /* _xf86cfg_stubs_h */
diff --git a/hw/xfree86/utils/xorgcfg/taller.xbm b/hw/xfree86/utils/xorgcfg/taller.xbm
new file mode 100644
index 000000000..c779300ea
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/taller.xbm
@@ -0,0 +1,8 @@
+#define taller_width 19
+#define taller_height 19
+static unsigned char taller_bits[] = {
+ 0x00, 0x02, 0x00, 0x00, 0x07, 0x00, 0x80, 0x0f, 0x00, 0xc0, 0x1f, 0x00,
+ 0xe0, 0x3f, 0x00, 0xf0, 0x7f, 0x00, 0xf8, 0xff, 0x00, 0xfc, 0xff, 0x01,
+ 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0xfc, 0xff, 0x01,
+ 0xf8, 0xff, 0x00, 0xf0, 0x7f, 0x00, 0xe0, 0x3f, 0x00, 0xc0, 0x1f, 0x00,
+ 0x80, 0x0f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x02, 0x00};
diff --git a/hw/xfree86/utils/xorgcfg/text-mode.c b/hw/xfree86/utils/xorgcfg/text-mode.c
new file mode 100644
index 000000000..ef4da2877
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/text-mode.c
@@ -0,0 +1,3353 @@
+/*
+ * 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/text-mode.c,v 1.22 2003/02/16 05:23:45 paulo Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _SCO_DS
+#include <curses.h>
+#else
+#include <ncurses.h>
+#endif
+#include <ctype.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/XKBstr.h>
+#include <X11/extensions/XKBrules.h>
+#include "cards.h"
+#include "config.h"
+#include "xf86config.h"
+#include "loader.h"
+
+#define XKB_RULES_DIR "/usr/X11R6/lib/X11/xkb/rules"
+
+#define CONTROL_A 1
+#define CONTROL_D 4
+#define CONTROL_E 5
+#define CONTROL_K 11
+#define TAB 9
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+void TextMode(void);
+
+static void ClearScreen(void);
+static void PaintWindow(WINDOW*, char*, int, int, int, int);
+static void PaintBox(WINDOW*, int, int, int, int);
+static void PaintButton(WINDOW*, char*, int, int, int);
+static void PrintWrap(WINDOW*, char*, int, int, int);
+static int Dialog(char*, char*, int, int, char*, char*, int);
+static void PaintItem(WINDOW*, char*, int, int);
+static int DialogMenu(char*, char*, int, int, int, int, char**, char*, char*, int);
+static void PaintCheckItem(WINDOW*, char*, int, int, int);
+static int DialogCheckBox(char*, char*, int, int, int, int, char**, char*, char*, char*);
+static char *DialogInput(char*, char*, int, int, char*, char*, char*, int);
+static void PaintScroller(WINDOW*, int, int, int);
+
+static int MouseConfig(void);
+static int KeyboardConfig(void);
+static int MonitorConfig(void);
+static int CardConfig(void);
+static int ScreenConfig(void);
+static int LayoutConfig(void);
+static int WriteXF86Config(void);
+
+static XF86ConfLayoutPtr CopyLayout(XF86ConfLayoutPtr);
+static XF86ConfAdjacencyPtr CopyAdjacency(XF86ConfAdjacencyPtr);
+static XF86ConfInputrefPtr CopyInputref(XF86ConfInputrefPtr);
+static XF86ConfInactivePtr CopyInactive(XF86ConfInactivePtr);
+static void FreeLayout(XF86ConfLayoutPtr);
+
+extern int string_to_parser_range(char*, parser_range*, int);
+#define PARSER_RANGE_SIZE 256
+/* string must have at least 256 bytes */
+extern int parser_range_to_string(char*, parser_range*, int);
+
+static Bool newconfig;
+
+static chtype screen_attr = A_NORMAL;
+static chtype dialog_attr = A_REVERSE;
+static chtype highlight_border_attr = A_REVERSE;
+static chtype shadow_border_attr = A_REVERSE;
+static chtype title_attr = A_NORMAL;
+static chtype button_active_attr = A_NORMAL;
+static chtype button_inactive_attr = A_NORMAL;
+static int menu_width, item_x;
+static char Edit[] = "Edit ";
+
+static char *main_menu[] = {
+#define CONF_MOUSE 0
+ "Configure mouse",
+#define CONF_KEYBOARD 1
+ "Configure keyboard",
+#define CONF_MONITOR 2
+ "Configure monitor",
+#define CONF_CARD 3
+ "Configure card",
+#define CONF_SCREEN 4
+ "Configure screen",
+#define CONF_LAYOUT 5
+ "Configure layout",
+#define CONF_FINISH 6
+ "Write XF86Config and quit",
+#define CONF_QUIT 7
+ "Quit",
+};
+
+void
+TextMode(void)
+{
+ static int first = 1;
+ int i, choice = CONF_MOUSE;
+
+#ifdef USE_MODULES
+ if (!nomodules)
+ LoaderInitializeOptions();
+#endif
+ initscr();
+ noecho();
+ nonl();
+ keypad(stdscr, TRUE);
+
+ if (first) {
+ const char *filename;
+
+ first = 0;
+
+ if (has_colors()) {
+ start_color();
+ init_pair(1, COLOR_BLACK, COLOR_BLACK);
+ screen_attr = A_BOLD | COLOR_PAIR(1);
+
+ init_pair(2, COLOR_BLACK, COLOR_WHITE);
+ dialog_attr = COLOR_PAIR(2);
+
+ init_pair(3, COLOR_BLACK, COLOR_WHITE);
+ shadow_border_attr = A_BOLD | COLOR_PAIR(3);
+
+ init_pair(4, COLOR_WHITE, COLOR_WHITE);
+ highlight_border_attr = A_BOLD | COLOR_PAIR(4);
+
+ init_pair(5, COLOR_WHITE, COLOR_BLUE);
+ title_attr = A_BOLD | COLOR_PAIR(5);
+ button_active_attr = title_attr;
+
+ init_pair(6, COLOR_WHITE, COLOR_BLACK);
+ button_inactive_attr = A_BOLD | COLOR_PAIR(6);
+ }
+
+ if ((filename = xf86openConfigFile(getuid() == 0 ?
+ CONFPATH : USER_CONFPATH,
+ XF86Config_path, NULL)) != NULL) {
+ XF86Config_path = (char *)filename;
+ if ((XF86Config = xf86readConfigFile()) == NULL) {
+ ClearScreen();
+ refresh();
+ Dialog("Configuration error",
+ "Error parsing configuration file.",
+ 7, 50, " Ok ", NULL, 0);
+ }
+ }
+ if (XF86Config == NULL) {
+ XF86Config = (XF86ConfigPtr)XtCalloc(1, sizeof(XF86ConfigRec));
+ newconfig = True;
+ }
+ else
+ newconfig = False;
+ }
+
+ ClearScreen();
+ refresh();
+
+ /*CONSTCOND*/
+ while (1) {
+ int cancel = FALSE;
+
+ ClearScreen();
+ refresh();
+ if (Dialog("XFree86 Configuration",
+ "This program will create the XF86Config file, based on "
+ "menu selections you make.\n"
+ "\n"
+ "The XF86Config file usually resides in /usr/X11R6/etc/X11 "
+ "or /etc/X11. A sample XF86Config file is supplied with "
+ "XFree86; it is configured for a standard VGA card and "
+ "monitor with 640x480 resolution. This program will ask for "
+ "a pathname when it is ready to write the file.\n"
+ "\n"
+ "You can either take the sample XF86Config as a base and "
+ "edit it for your configuration, or let this program "
+ "produce a base XF86Config file for your configuration and "
+ "fine-tune it.",
+ 20, 60, " Ok ", " Cancel ", 0) != 0)
+ break;
+
+ while (!cancel) {
+ ClearScreen();
+ refresh();
+ switch (DialogMenu("Main menu",
+ "Choose one of the options:",
+ 17, 60, 8, sizeof(main_menu) /
+ sizeof(main_menu[0]), main_menu,
+ " Ok ", " Cancel ", choice)) {
+ case CONF_MOUSE:
+ i = MouseConfig();
+ if (i > 0 && choice == CONF_MOUSE)
+ choice = CONF_KEYBOARD;
+ else if (i == 0)
+ choice = CONF_MOUSE;
+ break;
+ case CONF_KEYBOARD:
+ i = KeyboardConfig();
+ if (i > 0 && choice <= CONF_KEYBOARD)
+ choice = CONF_MONITOR;
+ else if (i == 0)
+ choice = CONF_KEYBOARD;
+ break;
+ case CONF_MONITOR:
+ i = MonitorConfig();
+ if (i > 0 && choice <= CONF_MONITOR)
+ choice = CONF_CARD;
+ else if (i == 0)
+ choice = CONF_MONITOR;
+ break;
+ case CONF_CARD:
+ i = CardConfig();
+ if (i > 0 && choice <= CONF_CARD)
+ choice = CONF_SCREEN;
+ else if (i == 0)
+ choice = CONF_CARD;
+ break;
+ case CONF_SCREEN:
+ i = ScreenConfig();
+ if (i > 0 && choice <= CONF_SCREEN)
+ choice = CONF_LAYOUT;
+ else if (i == 0)
+ choice = CONF_SCREEN;
+ break;
+ case CONF_LAYOUT:
+ i = LayoutConfig();
+ if (i > 0 && choice <= CONF_LAYOUT)
+ choice = CONF_FINISH;
+ else if (i == 0)
+ choice = CONF_LAYOUT;
+ break;
+ case CONF_FINISH:
+ if (WriteXF86Config() < 0)
+ break;
+ /*FALLTROUGH*/
+ case CONF_QUIT:
+ endwin();
+ exit(0);
+ default:
+ cancel = TRUE;
+ break;
+ }
+ }
+ }
+
+ endwin();
+}
+
+static int
+WriteXF86Config(void)
+{
+ char *xf86config;
+
+ ClearScreen();
+ refresh();
+ xf86config = DialogInput("Write XF86Config", "Write configuration to file:",
+ 10, 60, XF86Config_path ? XF86Config_path :
+ "/etc/X11/XF86Config", " Ok ", " Cancel ", 0);
+
+ if (xf86config == NULL)
+ return (-1);
+
+ if (newconfig) {
+ if (XF86Config->conf_modules == NULL) {
+ static char *modules[] = {"extmod", "glx", "dri", "dbe",
+ "record", "xtrap", "type1", "speedo"};
+ XF86LoadPtr load;
+ int i;
+
+ XF86Config->conf_modules = (XF86ConfModulePtr)
+ XtCalloc(1, sizeof(XF86ConfModuleRec));
+
+ XF86Config->conf_modules->mod_comment =
+ XtNewString("\t# Load \"freetype\"\n"
+ "\t# Load \"xtt\"\n");
+
+ for (i = 0; i < sizeof(modules) / sizeof(modules[0]); i++) {
+ load = (XF86LoadPtr)XtCalloc(1, sizeof(XF86LoadRec));
+ load->load_name = XtNewString(modules[i]);
+ XF86Config->conf_modules->mod_load_lst =
+ xf86addModule(XF86Config->conf_modules->mod_load_lst, load);
+ }
+ }
+ }
+
+ if (!xf86writeConfigFile(xf86config, XF86Config)) {
+ char msg[1024];
+
+ XmuSnprintf(msg, sizeof(msg), "Failed to write configuration file %s.",
+ xf86config);
+ ClearScreen();
+ refresh();
+ (void)Dialog("Write failed!", msg, 8, 60, " Ok ", NULL, 0);
+ XtFree(xf86config);
+ return (-1);
+ }
+ XtFree(xf86config);
+
+ return (1);
+}
+
+static char *protocols[] = {
+#ifdef SCO
+ "OsMouse",
+#endif
+#ifdef WSCONS_SUPPORT
+ "wsmouse",
+#endif
+ "Auto",
+ "SysMouse",
+ "MouseSystems",
+ "BusMouse",
+ "PS/2",
+ "Microsoft",
+#ifndef __FreeBSD__
+ "ImPS/2",
+ "ExplorerPS/2",
+ "GlidePointPS/2",
+ "MouseManPlusPS/2",
+ "NetMousePS/2",
+ "NetScrollPS/2",
+ "ThinkingMousePS/2",
+#endif
+ "AceCad",
+ "GlidePoint",
+ "IntelliMouse",
+ "Logitech",
+ "MMHitTab",
+ "MMSeries",
+ "MouseMan",
+ "ThinkingMouse",
+};
+
+static int
+MouseConfig(void)
+{
+ int i, nlist, def, proto, emul;
+ char **list = NULL, *device, *str;
+ XF86ConfInputPtr *inputs = NULL;
+ XF86ConfInputPtr input = XF86Config->conf_input_lst;
+ XF86OptionPtr option;
+
+ nlist = 0;
+ while (input) {
+ if (strcmp(input->inp_driver, "mouse") == 0) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
+ list[nlist] = XtMalloc(sizeof(Edit) +
+ strlen(input->inp_identifier) + 1);
+ sprintf(list[nlist], "%s%s", Edit, input->inp_identifier);
+ inputs = (XF86ConfInputPtr*)XtRealloc((XtPointer)inputs, (nlist + 1) *
+ sizeof(XF86ConfInputPtr));
+ inputs[nlist] = input;
+ ++nlist;
+ }
+ input = (XF86ConfInputPtr)(input->list.next);
+ }
+
+ input = NULL;
+
+ if (nlist) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
+ list[nlist++] = XtNewString("Add new mouse");
+ if (nlist == 2) {
+ i = strlen("Remove ") + strlen(inputs[0]->inp_identifier) + 1;
+ list[nlist] = XtMalloc(i);
+ XmuSnprintf(list[nlist], i, "Remove %s", inputs[0]->inp_identifier);
+ ++nlist;
+ }
+ else
+ list[nlist++] = XtNewString("Remove mouse");
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Mouse configuration",
+ "You can edit or remove a previously configured mouse, "
+ "or add a new one.", 14, 60, 4, nlist, list,
+ " Ok ", " Cancel ", 0);
+ if (i < 0) {
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)inputs);
+ return (-1);
+ }
+ if (nlist > 2 && i == nlist - 1) {
+ if (nlist > 3) {
+ for (i = 0; i < nlist - 2; i++) {
+ /* XXX Remove the "Edit " from list entries */
+ memmove(list[i], list[i] + sizeof(Edit) - 1,
+ strlen(list[i]) - sizeof(Edit) + 2);
+ }
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Remove mouse",
+ "Select which mouse to remove",
+ 13, 60, 4, nlist - 2, list,
+ " Remove ", " Cancel ", 0);
+ if (i < 0) {
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)inputs);
+ return (-1);
+ }
+ input = inputs[i];
+ }
+ else
+ input = inputs[0];
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)inputs);
+ xf86removeInput(XF86Config, input);
+ return (0);
+ }
+ if (i < nlist - 2)
+ input = inputs[i];
+ }
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)inputs);
+
+ if (input == NULL) {
+ char label[32];
+
+ input = (XF86ConfInputPtr)XtCalloc(1, sizeof(XF86ConfInputRec));
+ XmuSnprintf(label, sizeof(label), "Mouse%d", nlist ? nlist - 2 : 0);
+ ClearScreen();
+ refresh();
+ input->inp_identifier =
+ DialogInput("Mouse identifier",
+ "Enter an identifier for your mouse definition:",
+ 11, 40, label,
+ " Next >>", " Cancel ", 0);
+ if (input->inp_identifier == NULL) {
+ XtFree((XtPointer)input);
+ return (-1);
+ }
+ }
+
+ def = 0;
+ option = xf86findOption(input->inp_option_lst, "Protocol");
+ if (option)
+ for (i = 0; i < sizeof(protocols)/sizeof(protocols[0]); i++)
+ if (strcasecmp(option->opt_val, protocols[i]) == 0) {
+ def = i;
+ break;
+ }
+
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Select mouse protocol",
+ "If you have a serial mouse, it probably will work with "
+ "the \"Auto\" protocol. But, if it is an old serial "
+ "mouse probably it is not PNP; in that case, most serial "
+ "mouses understand the \"Microsoft\" protocol.",
+ 19, 60, 7, sizeof(protocols) /
+ sizeof(protocols[0]), protocols, " Next >>", " Cancel ", def);
+ if (i < 0) {
+ if (input->inp_driver == NULL) {
+ XtFree(input->inp_driver);
+ XtFree((XtPointer)input);
+ }
+ return (i);
+ }
+ proto = i;
+
+ def = 0;
+ if (input->inp_driver) {
+ option = xf86findOption(input->inp_option_lst, "Emulate3Buttons");
+ def = option ? 0 : 1;
+ }
+ ClearScreen();
+ refresh();
+ i = Dialog("Mouse 3 buttons emulation",
+ "If your mouse has only two buttons, it is recommended that "
+ "you enable Emulate3Buttons.\n"
+ "\n"
+ "Do you want to enable Emulate3Buttons?",
+ 10, 60, " Yes ", " No ", def);
+ if (i < 0)
+ return (i);
+ emul = !i;
+
+ str = NULL;
+ option = xf86findOption(input->inp_option_lst, "Device");
+ if (option)
+ str = option->opt_val;
+ if (str == NULL)
+#ifdef WSCONS_SUPPORT
+ str = "/dev/wsmouse";
+#elif defined(__FreeBSD__)
+ str = "/dev/sysmouse";
+#else
+ str = "/dev/mouse";
+#endif
+
+ ClearScreen();
+ refresh();
+ device = DialogInput("Select mouse device",
+ "Enter mouse device:", 10, 40, str,
+ " Finish ", " Cancel ", 0);
+ if (device == NULL) {
+ if (input->inp_driver == NULL) {
+ XtFree(input->inp_driver);
+ XtFree((XtPointer)input);
+ }
+ return (-1);
+ }
+
+ /* Finish mouse configuration */
+ option = xf86findOption(input->inp_option_lst, "Protocol");
+ if (option) {
+ XtFree((XtPointer)option->opt_val);
+ option->opt_val = XtNewString(protocols[proto]);
+ }
+ else
+ input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
+ XtNewString("Protocol"), XtNewString(protocols[proto]));
+
+ option = xf86findOption(input->inp_option_lst, "Emulate3Buttons");
+ if (option && !emul) {
+ xf86removeOption(&input->inp_option_lst, "Emulate3Buttons");
+ }
+ else if (option == NULL && emul)
+ input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
+ XtNewString("Emulate3Buttons"), NULL);
+
+ option = xf86findOption(input->inp_option_lst, "Device");
+ if (option) {
+ XtFree((XtPointer)option->opt_val);
+ option->opt_val = device;
+ }
+ else
+ input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
+ XtNewString("Device"), device);
+
+ if (input->inp_driver == NULL) {
+ input->inp_driver = XtNewString("mouse");
+ XF86Config->conf_input_lst =
+ xf86addInput(XF86Config->conf_input_lst, input);
+ }
+
+ return (1);
+}
+
+static int
+KeyboardConfig(void)
+{
+ int i;
+ char *rulesfile;
+ static int first = 1;
+ static XkbRF_RulesPtr rules;
+ static char **models, **layouts;
+ XF86ConfInputPtr *inputs = NULL, input = XF86Config->conf_input_lst;
+ char **list = NULL, *model, *layout;
+ int nlist, def;
+ XF86OptionPtr option;
+
+ nlist = 0;
+ while (input) {
+ if (strcmp(input->inp_driver, "keyboard") == 0) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
+ list[nlist] = XtMalloc(sizeof(Edit) +
+ strlen(input->inp_identifier) + 1);
+ sprintf(list[nlist], "%s%s", Edit, input->inp_identifier);
+ inputs = (XF86ConfInputPtr*)XtRealloc((XtPointer)inputs, (nlist + 1) *
+ sizeof(XF86ConfInputPtr));
+ inputs[nlist] = input;
+ ++nlist;
+ }
+ input = (XF86ConfInputPtr)(input->list.next);
+ }
+
+ input = NULL;
+
+ if (nlist) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
+ list[nlist++] = XtNewString("Add new keyboard");
+ if (nlist == 2) {
+ i = strlen("Remove ") + strlen(inputs[0]->inp_identifier) + 1;
+ list[nlist] = XtMalloc(i);
+ XmuSnprintf(list[nlist], i, "Remove %s", inputs[0]->inp_identifier);
+ ++nlist;
+ }
+ else
+ list[nlist++] = XtNewString("Remove keyboard");
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Keyboard configuration",
+ "You can edit or remove a previously configured "
+ "keyboard, or add a new one.", 14, 60, 4, nlist, list,
+ " Ok ", " Cancel ", 0);
+ if (i < 0) {
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)inputs);
+ return (-1);
+ }
+ if (nlist > 2 && i == nlist - 1) {
+ if (nlist > 3) {
+ for (i = 0; i < nlist - 2; i++) {
+ /* XXX Remove the "Edit " from list entries */
+ memmove(list[i], list[i] + sizeof(Edit) - 1,
+ strlen(list[i]) - sizeof(Edit) + 2);
+ }
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Remove keyboard",
+ "Select which keyboard to remove",
+ 13, 60, 4, nlist - 2, list,
+ " Remove ", " Cancel ", 0);
+ if (i < 0) {
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)inputs);
+ return (-1);
+ }
+ input = inputs[i];
+ }
+ else
+ input = inputs[0];
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)inputs);
+ xf86removeInput(XF86Config, input);
+ return (0);
+ }
+ if (i < nlist - 2)
+ input = inputs[i];
+ }
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)inputs);
+
+ if (input == NULL) {
+ char label[32];
+
+ input = (XF86ConfInputPtr)XtCalloc(1, sizeof(XF86ConfInputRec));
+ XmuSnprintf(label, sizeof(label), "Keyboard%d", nlist ? nlist - 2 : 0);
+ ClearScreen();
+ refresh();
+ input->inp_identifier =
+ DialogInput("Keyboard identifier",
+ "Enter an identifier for your keyboard definition:",
+ 11, 40, label,
+ " Next >>", " Cancel ", 0);
+ if (input->inp_identifier == NULL) {
+ XtFree((XtPointer)input);
+ return (-1);
+ }
+ }
+
+ if (first) {
+ first = 0;
+#ifdef XFREE98_XKB
+ rulesfile = XKB_RULES_DIR "/xfree98";
+#else
+ rulesfile = XKB_RULES_DIR "/xfree86";
+#endif
+ rules = XkbRF_Load(rulesfile, "", True, False);
+ if (rules == NULL) {
+ ClearScreen();
+ refresh();
+ Dialog("Configuration error",
+ "XKB rules file not found.\n"
+ "\n"
+ "Keyboard XKB options will be set to default values.",
+ 10, 50, " Ok ", NULL, 0);
+ if (input->inp_driver == NULL) {
+ input->inp_option_lst =
+ xf86addNewOption(input->inp_option_lst,
+ XtNewString("XkbModel"), XtNewString("pc101"));
+ input->inp_option_lst =
+ xf86addNewOption(input->inp_option_lst,
+ XtNewString("XkbLayout"), XtNewString("us"));
+ input->inp_driver = XtNewString("keyboard");
+ XF86Config->conf_input_lst =
+ xf86addInput(XF86Config, input);
+ }
+ return (0);
+ }
+ models = (char**)XtMalloc(sizeof(char*) * rules->models.num_desc);
+ for (i = 0; i < rules->models.num_desc; i++)
+ models[i] = XtNewString(rules->models.desc[i].desc);
+ layouts = (char**)XtMalloc(sizeof(char*) * rules->layouts.num_desc);
+ for (i = 0; i < rules->layouts.num_desc; i++)
+ layouts[i] = XtNewString(rules->layouts.desc[i].desc);
+ }
+ else if (rules == NULL)
+ return (-1);
+
+ def = 0;
+ option = xf86findOption(input->inp_option_lst, "XkbModel");
+ if (option) {
+ for (i = 0; i < rules->models.num_desc; i++)
+ if (strcasecmp(option->opt_val, rules->models.desc[i].name) == 0) {
+ def = i;
+ break;
+ }
+ }
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Keyboard model",
+ "Please select one of the following keyboard types that is "
+ "the better description of your keyboard. If nothing really "
+ "matches, choose \"Generic 101-key PC\".\n",
+ 20, 60, 9, rules->models.num_desc,
+ models, " Next >>", " Cancel ", def);
+ if (i < 0)
+ return (i);
+ model = rules->models.desc[i].name;
+
+ def = 0;
+ option = xf86findOption(input->inp_option_lst, "XkbLayout");
+ if (option) {
+ for (i = 0; i < rules->layouts.num_desc; i++)
+ if (strcasecmp(option->opt_val, rules->layouts.desc[i].name) == 0) {
+ def = i;
+ break;
+ }
+ }
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Keyboard layout",
+ "Select keyboard layout:",
+ 20, 60, 11, rules->layouts.num_desc,
+ layouts, " Finish ", " Cancel ", def);
+ if (i < 0)
+ return (i);
+ layout = rules->layouts.desc[i].name;
+
+ /* Finish keyboard configuration */
+ option = xf86findOption(input->inp_option_lst, "XkbModel");
+ if (option) {
+ XtFree((XtPointer)option->opt_val);
+ option->opt_val = XtNewString(model);
+ }
+ else
+ input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
+ XtNewString("XkbModel"), XtNewString(model));
+
+ option = xf86findOption(input->inp_option_lst, "XkbLayout");
+ if (option) {
+ XtFree((XtPointer)option->opt_val);
+ option->opt_val = XtNewString(layout);
+ }
+ else
+ input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
+ XtNewString("XkbLayout"), XtNewString(layout));
+
+ if (input->inp_driver == NULL) {
+ input->inp_driver = XtNewString("keyboard");
+ XF86Config->conf_input_lst =
+ xf86addInput(XF86Config->conf_input_lst, input);
+ }
+
+ return (1);
+}
+
+static char *hsync[] = {
+#define CONF_MONITOR_HSYNC 0
+ "Enter your own horizontal sync range",
+ "31.5; Standard VGA, 640x480 @ 60 Hz",
+ "31.5 - 35.1; Super VGA, 800x600 @ 56 Hz",
+ "31.5, 35.5; 8514 Compatible, 1024x768 @ 87 Hz interlaced (no 800x600)",
+ "31.5, 35.15, 35.5; Super VGA, 1024x768 @ 87 Hz int., 800x600 @ 56 Hz",
+ "31.5 - 37.9; Extended Super VGA, 800x600 @ 60 Hz, 640x480 @ 72 Hz",
+ "31.5 - 48.5; Non-Interlaced SVGA, 1024x768 @ 60 Hz, 800x600 @ 72 Hz",
+ "31.5 - 57.0; High Frequency SVGA, 1024x768 @ 70 Hz",
+ "31.5 - 64.3; Monitor that can do 1280x1024 @ 60 Hz",
+ "31.5 - 79.0; Monitor that can do 1280x1024 @ 74 Hz",
+ "31.5 - 82.0; Monitor that can do 1280x1024 @ 76 Hz",
+};
+
+static char *vrefresh[] = {
+#define CONF_MONITOR_VREFRESH 0
+ "Enter your own vertical sync range",
+ "50 - 70",
+ "50 - 90",
+ "50 - 100",
+ "40 - 150",
+};
+
+static int
+MonitorConfig(void)
+{
+ int i;
+ XF86ConfMonitorPtr *monitors = NULL, monitor = XF86Config->conf_monitor_lst;
+ char **list = NULL, *identifier = NULL, *tmp;
+ int nlist, def;
+ char hsync_str[256], vrefresh_str[256];
+
+ hsync_str[0] = vrefresh_str[0] = '\0';
+ nlist = 0;
+ while (monitor) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
+ list[nlist] = XtMalloc(sizeof(Edit) +
+ strlen(monitor->mon_identifier) + 1);
+ sprintf(list[nlist], "%s%s", Edit, monitor->mon_identifier);
+ monitors = (XF86ConfMonitorPtr*)XtRealloc((XtPointer)monitors, (nlist + 1) *
+ sizeof(XF86ConfMonitorPtr));
+ monitors[nlist] = monitor;
+ ++nlist;
+ monitor = (XF86ConfMonitorPtr)(monitor->list.next);
+ }
+
+ monitor = NULL;
+
+ if (nlist) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
+ list[nlist++] = XtNewString("Add new monitor");
+ if (nlist == 2) {
+ i = strlen("Remove ") + strlen(monitors[0]->mon_identifier) + 1;
+ list[nlist] = XtMalloc(i);
+ XmuSnprintf(list[nlist], i, "Remove %s", monitors[0]->mon_identifier);
+ ++nlist;
+ }
+ else
+ list[nlist++] = XtNewString("Remove monitor");
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Monitor configuration",
+ "You can edit or remove a previously configured "
+ "monitor, or add a new one.", 14, 60, 4, nlist, list,
+ " Ok ", " Cancel ", 0);
+ if (i < 0) {
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)monitors);
+ return (-1);
+ }
+ if (nlist > 2 && i == nlist - 1) {
+ if (nlist > 3) {
+ for (i = 0; i < nlist - 2; i++) {
+ /* XXX Remove the "Edit " from list entries */
+ memmove(list[i], list[i] + sizeof(Edit) - 1,
+ strlen(list[i]) - sizeof(Edit) + 2);
+ }
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Remove monitor",
+ "Select which monitor to remove",
+ 13, 60, 4, nlist - 2, list,
+ " Remove ", " Cancel ", 0);
+ if (i < 0) {
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)monitors);
+ return (-1);
+ }
+ monitor = monitors[i];
+ }
+ else
+ monitor = monitors[0];
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)monitors);
+ xf86removeMonitor(XF86Config, monitor);
+ return (0);
+ }
+ if (i < nlist - 2)
+ monitor = monitors[i];
+ }
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)monitors);
+
+ if (monitor == NULL) {
+ char label[32];
+
+ monitor = (XF86ConfMonitorPtr)XtCalloc(1, sizeof(XF86ConfMonitorRec));
+ XmuSnprintf(label, sizeof(label), "Monitor%d", nlist ? nlist - 2 : 0);
+ ClearScreen();
+ refresh();
+ identifier =
+ DialogInput("Monitor identifier",
+ "Enter an identifier for your monitor definition:",
+ 11, 40, label,
+ " Next >>", " Cancel ", 0);
+ if (identifier == NULL) {
+ XtFree((XtPointer)monitor);
+ return (-1);
+ }
+ }
+
+ if (monitor->mon_identifier == NULL) {
+ ClearScreen();
+ refresh();
+ i = Dialog("Monitor configuration",
+ "Now we want to set the specifications of the monitor. The "
+ "two critical parameters are the vertical refresh rate, which "
+ "is the rate at which the whole screen is refreshed, and most "
+ "importantly the horizontal sync rate, which is the rate at "
+ "which scanlines are displayed.\n"
+ "\n"
+ "The valid range for horizontal sync and vertical sync should "
+ "be documented in the manual of your monitor.",
+ 15, 60, " Next >>", " Cancel ", 0);
+ if (i != 0) {
+ XtFree(identifier);
+ XtFree((XtPointer)monitor);
+ return (-1);
+ }
+ }
+
+ def = 0;
+ if (monitor->mon_identifier) {
+ int len;
+
+ parser_range_to_string(hsync_str, &(monitor->mon_hsync[0]),
+ monitor->mon_n_hsync);
+ len = strlen(hsync_str);
+ for (i = 1; i < sizeof(hsync) / sizeof(hsync[0]); i++) {
+ tmp = strchr(hsync[i], ';');
+ if (strncmp(hsync_str, hsync[i], len) == 0) {
+ def = i;
+ break;
+ }
+ }
+ }
+ if (hsync_str[0] == '\0')
+ strcpy(hsync_str, "31.5");
+
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Monitor HorizSync",
+ "You must indicate the horizontal sync range of your "
+ "monitor. You can either select one of the predefined "
+ "ranges below that correspond to industry-standard monitor "
+ "types, or give a specific range.",
+ 22, 78, 11, sizeof(hsync) /
+ sizeof(hsync[0]), hsync, " Next >>", " Cancel ", def);
+ if (i < 0) {
+ if (monitor->mon_identifier == NULL) {
+ XtFree(identifier);
+ XtFree((XtPointer)monitor);
+ }
+ return (-1);
+ }
+ if (i == CONF_MONITOR_HSYNC) {
+ ClearScreen();
+ refresh();
+ tmp = DialogInput("Monitor HorizSync",
+ "Please enter the horizontal sync range of your "
+ "monitor, in the format used in the table of monitor "
+ "types above. You can either specify one or more "
+ "continuous ranges (e.g. 15-25, 30-50), or one or more "
+ "fixed sync frequencies.\n"
+ "\n"
+ "Horizontal sync range:", 16, 62, hsync_str,
+ " Ok ", " Cancel ", def);
+ if (tmp == NULL) {
+ if (monitor->mon_identifier == NULL) {
+ XtFree(identifier);
+ XtFree((XtPointer)monitor);
+ }
+ return (-1);
+ }
+ XmuSnprintf(hsync_str, sizeof(hsync_str), "%s", tmp);
+ XtFree(tmp);
+ }
+ else {
+ tmp = strchr(hsync[i], ';');
+ strncpy(hsync_str, hsync[i], tmp - hsync[i]);
+ hsync_str[tmp - hsync[i]] = '\0';
+ }
+
+ def = 0;
+ if (monitor->mon_identifier) {
+ parser_range_to_string(vrefresh_str, &(monitor->mon_vrefresh[0]),
+ monitor->mon_n_vrefresh);
+ for (i = 1; i < sizeof(vrefresh) / sizeof(vrefresh[0]); i++) {
+ if (strcmp(vrefresh_str, vrefresh[i]) == 0) {
+ def = i;
+ break;
+ }
+ }
+ }
+ if (vrefresh_str[0] == '\0')
+ strcpy(vrefresh_str, "50 - 70");
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Monitor VertRefresh",
+ "You must indicate the vertical sync range of your monitor. "
+ "You can either select one of the predefined ranges below "
+ "that correspond to industry-standard monitor types, or "
+ "give a specific range. For interlaced modes, the number "
+ "that counts is the high one (e.g. 87 Hz rather than 43 Hz).",
+ 19, 60, 5, sizeof(vrefresh) /
+ sizeof(vrefresh[0]), vrefresh, " Finish ", " Cancel ", def);
+ if (i < 0) {
+ if (monitor->mon_identifier == NULL) {
+ XtFree(identifier);
+ XtFree((XtPointer)monitor);
+ }
+ return (i);
+ }
+ if (i == CONF_MONITOR_VREFRESH) {
+ ClearScreen();
+ refresh();
+ tmp = DialogInput("Monitor VertRefresh",
+ "Vertical sync range:", 10, 50, vrefresh_str,
+ " Done ", " Cancel ", 0);
+ if (tmp == NULL) {
+ if (monitor->mon_identifier == NULL) {
+ XtFree(identifier);
+ XtFree((XtPointer)monitor);
+ }
+ return (-1);
+ }
+ XmuSnprintf(vrefresh_str, sizeof(vrefresh_str), "%s", tmp);
+ XtFree(tmp);
+ }
+ else
+ strcpy(vrefresh_str, vrefresh[i]);
+
+ /* Finish monitor configuration */
+ monitor->mon_n_hsync = string_to_parser_range(hsync_str,
+ &(monitor->mon_hsync[0]), CONF_MAX_HSYNC);
+ monitor->mon_n_vrefresh = string_to_parser_range(vrefresh_str,
+ &(monitor->mon_vrefresh[0]), CONF_MAX_VREFRESH);
+ if (monitor->mon_identifier == NULL) {
+ monitor->mon_identifier = identifier;
+ XF86Config->conf_monitor_lst =
+ xf86addMonitor(XF86Config->conf_monitor_lst, monitor);
+ }
+
+ return (1);
+}
+
+static int
+CardConfig(void)
+{
+ int i;
+ XF86ConfDevicePtr *devices = NULL, device = XF86Config->conf_device_lst;
+ char **list = NULL, *identifier = NULL, *driver, *busid, *tmp;
+ int nlist, def;
+ CardsEntry *entry = NULL;
+ static char **drivers;
+ static int ndrivers;
+ static char *xdrivers[] = {
+ "apm",
+ "ark",
+ "ati",
+ "r128",
+ "radeon",
+ "chips",
+ "cirrus",
+ "cyrix",
+ "fbdev",
+ "glint",
+ "i128",
+ "i740",
+ "i810",
+ "imstt",
+ "mga",
+ "neomagic",
+ "nv",
+ "rendition",
+ "s3",
+ "s3virge",
+ "savage",
+ "siliconmotion",
+ "sis",
+ "tdfx",
+ "tga",
+ "trident",
+ "tseng",
+ "vmware",
+ "vga",
+ "vesa",
+ };
+
+#ifdef USE_MODULES
+ if (!nomodules) {
+ xf86cfgModuleOptions *opts = module_options;
+
+ drivers = NULL;
+ ndrivers = 0;
+ while (opts) {
+ if (opts->type == VideoModule) {
+ ++ndrivers;
+ drivers = (char**)XtRealloc((XtPointer)drivers,
+ ndrivers * sizeof(char*));
+ /* XXX no private copy */
+ drivers[ndrivers - 1] = opts->name;
+ }
+ opts = opts->next;
+ }
+ }
+ else
+#endif
+ {
+ ndrivers = sizeof(xdrivers) / sizeof(xdrivers[0]);
+ drivers = xdrivers;
+ }
+
+ nlist = 0;
+ while (device) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
+ list[nlist] = XtMalloc(sizeof(Edit) +
+ strlen(device->dev_identifier) + 1);
+ sprintf(list[nlist], "%s%s", Edit, device->dev_identifier);
+ devices = (XF86ConfDevicePtr*)XtRealloc((XtPointer)devices, (nlist + 1) *
+ sizeof(XF86ConfDevicePtr));
+ devices[nlist] = device;
+ ++nlist;
+ device = (XF86ConfDevicePtr)(device->list.next);
+ }
+
+ device = NULL;
+
+ if (nlist) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
+ list[nlist++] = XtNewString("Add new card");
+ if (nlist == 2) {
+ i = strlen("Remove ") + strlen(devices[0]->dev_identifier) + 1;
+ list[nlist] = XtMalloc(i);
+ XmuSnprintf(list[nlist], i, "Remove %s", devices[0]->dev_identifier);
+ ++nlist;
+ }
+ else
+ list[nlist++] = XtNewString("Remove device");
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Card configuration",
+ "You can edit or remove a previously configured "
+ "card, or add a new one.", 14, 60, 4, nlist, list,
+ " Ok ", " Cancel ", 0);
+ if (i < 0) {
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)devices);
+ return (-1);
+ }
+ if (nlist > 2 && i == nlist - 1) {
+ if (nlist > 3) {
+ for (i = 0; i < nlist - 2; i++) {
+ /* XXX Remove the "Edit " from list entries */
+ memmove(list[i], list[i] + sizeof(Edit) - 1,
+ strlen(list[i]) - sizeof(Edit) + 2);
+ }
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Remove card",
+ "Select which card to remove",
+ 13, 60, 4, nlist - 2, list,
+ " Remove ", " Cancel ", 0);
+ if (i < 0) {
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)devices);
+ return (-1);
+ }
+ device = devices[i];
+ }
+ else
+ device = devices[0];
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)devices);
+ xf86removeDevice(XF86Config, device);
+ return (0);
+ }
+ if (i < nlist - 2)
+ device = devices[i];
+ }
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)devices);
+
+ if (device == NULL) {
+ char label[32];
+
+ device = (XF86ConfDevicePtr)XtCalloc(1, sizeof(XF86ConfDeviceRec));
+ device->dev_chipid = device->dev_chiprev = device->dev_irq = -1;
+ XmuSnprintf(label, sizeof(label), "Card%d", nlist ? nlist - 2 : 0);
+ ClearScreen();
+ refresh();
+ identifier =
+ DialogInput("Card identifier",
+ "Enter an identifier for your card definition:",
+ 11, 40, label,
+ " Next >>", " Cancel ", 0);
+ if (identifier == NULL) {
+ XtFree((XtPointer)device);
+ return (-1);
+ }
+ }
+
+ ClearScreen();
+ refresh();
+ if (Dialog("Card configuration",
+ "Now we must configure video card specific settings. At this "
+ "point you can choose to make a selection out of a database of "
+ "video card definitions.\n"
+ "\n"
+ "The database entries include information about the chipset, "
+ "what driver to run, the Ramdac and ClockChip, and comments "
+ "that will be included in the Device section. However, a lot "
+ "of definitions only hint about what driver to run (based on "
+ "the chipset the card uses) and are untested.\n"
+ "\n"
+ "Do you want to look at the card database?",
+ 18, 60, " Yes ", " No ", device->dev_identifier != NULL) == 0) {
+ static char **cards;
+ static int ncards;
+
+ if (cards == NULL) {
+ ReadCardsDatabase();
+ cards = GetCardNames(&ncards);
+ cards = (char**)XtRealloc((XtPointer)cards,
+ (ncards + 1) * sizeof(char*));
+ for (i = ncards; i > 0; i--)
+ cards[i] = cards[i - 1];
+ cards[0] = "** Unlisted card **";
+ ++ncards;
+ }
+ if (device->dev_card)
+ entry = LookupCard(device->dev_card);
+ def = 0;
+ if (entry) {
+ for (i = 0; i < NumCardsEntry; i++)
+ if (strcasecmp(CardsDB[i]->name, entry->name) == 0) {
+ def = i + 1;
+ break;
+ }
+ /* make sure entry is set to null again */
+ entry = NULL;
+ }
+
+ i = DialogMenu("Card database",
+ "Select name that better matches your card:",
+ 20, 70, 11, ncards, cards, "Next >>", " Cancel ", def);
+ if (i > 0)
+ entry = LookupCard(cards[i]);
+ }
+
+ def = 0;
+ tmp = device->dev_driver ? device->dev_driver : entry && entry->driver ?
+ entry->driver : "vga";
+ for (i = 0; i < ndrivers; i++)
+ if (strcmp(drivers[i], tmp) == 0) {
+ def = i;
+ break;
+ }
+
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Card driver",
+ "You can select the driver for your card here, or just press "
+ "Enter to use the default/current:", 20, 50, 9,
+ ndrivers, drivers, " Ok ", " Cancel ", def);
+ if (i < 0) {
+ if (device->dev_identifier == NULL) {
+ XtFree(identifier);
+ XtFree((XtPointer)device);
+ }
+ return (-1);
+ }
+ driver = ndrivers ? drivers[i] : "vga";
+
+ ClearScreen();
+ refresh();
+ tmp = device->dev_busid ? device->dev_busid : "";
+ busid = DialogInput("Card BusID",
+ "You normally does not need to fill this field "
+ "if you have only one video card:", 11, 50, tmp,
+ " Finish ", " Cancel ", 0);
+
+ /* Finish card configuration */
+ if (entry) {
+ XtFree(device->dev_card);
+ device->dev_card = XtNewString(entry->name);
+ if (entry->chipset) {
+ XtFree(device->dev_chipset);
+ device->dev_chipset = XtNewString(entry->chipset);
+ }
+ if (entry->ramdac) {
+ XtFree(device->dev_ramdac);
+ device->dev_ramdac = XtNewString(entry->ramdac);
+ }
+ if (entry->clockchip) {
+ XtFree(entry->clockchip);
+ device->dev_clockchip = XtNewString(entry->clockchip);
+ }
+ }
+ if (busid) {
+ XtFree(device->dev_busid);
+ if (*busid)
+ device->dev_busid = busid;
+ else {
+ device->dev_busid = NULL;
+ XtFree(busid);
+ }
+ }
+ XtFree(device->dev_driver);
+ device->dev_driver = XtNewString(driver);
+ if (device->dev_identifier == NULL) {
+ device->dev_identifier = identifier;
+ XF86Config->conf_device_lst =
+ xf86addDevice(XF86Config->conf_device_lst, device);
+ }
+
+ return (1);
+}
+
+static char *depths[] = {
+ "1 bit, monochrome",
+ "4 bit, 16 colors",
+ "8 bit, 256 colors",
+ "15 bits, 32Kb colors",
+ "16 bits, 65Kb colors",
+ "24 bits, 16Mb colors",
+};
+
+static char *modes[] = {
+ "1600x1200",
+ "1400x1050",
+ "1280x1024",
+ "1280x960",
+ "1152x864",
+ "1024x768",
+ "800x600",
+ "640x480",
+ "640x400",
+ "512x384",
+ "400x300",
+ "320x240",
+ "320x200",
+};
+
+static int
+ScreenConfig(void)
+{
+ int i, disp_allocated;
+ XF86ConfScreenPtr *screens = NULL, screen = XF86Config->conf_screen_lst;
+ char **list = NULL, *identifier = NULL;
+ int nlist, def;
+ XF86ConfDevicePtr device = NULL;
+ XF86ConfMonitorPtr monitor = NULL;
+ XF86ConfDisplayPtr display;
+ XF86ModePtr mode, ptr = NULL;
+ char *checks;
+
+ nlist = 0;
+ while (screen) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
+ list[nlist] = XtMalloc(sizeof(Edit) +
+ strlen(screen->scrn_identifier) + 1);
+ sprintf(list[nlist], "%s%s", Edit, screen->scrn_identifier);
+ screens = (XF86ConfScreenPtr*)XtRealloc((XtPointer)screens, (nlist + 1) *
+ sizeof(XF86ConfScreenPtr));
+ screens[nlist] = screen;
+ ++nlist;
+ screen = (XF86ConfScreenPtr)(screen->list.next);
+ }
+
+ screen = NULL;
+
+ if (nlist) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
+ list[nlist++] = XtNewString("Add new screen");
+ if (nlist == 2) {
+ i = strlen("Remove ") + strlen(screens[0]->scrn_identifier) + 1;
+ list[nlist] = XtMalloc(i);
+ XmuSnprintf(list[nlist], i, "Remove %s", screens[0]->scrn_identifier);
+ ++nlist;
+ }
+ else
+ list[nlist++] = XtNewString("Remove screen");
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Screen configuration",
+ "You can edit or remove a previously configured "
+ "screen, or add a new one.", 14, 60, 4, nlist, list,
+ " Ok ", " Cancel ", 0);
+ if (i < 0) {
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)screens);
+ return (-1);
+ }
+ if (nlist > 2 && i == nlist - 1) {
+ if (nlist > 3) {
+ for (i = 0; i < nlist - 2; i++) {
+ /* XXX Remove the "Edit " from list entries */
+ memmove(list[i], list[i] + sizeof(Edit) - 1,
+ strlen(list[i]) - sizeof(Edit) + 2);
+ }
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Remove screen",
+ "Select which screen to remove",
+ 13, 60, 4, nlist - 2, list,
+ " Remove ", " Cancel ", 0);
+ if (i < 0) {
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)screens);
+ return (-1);
+ }
+ screen = screens[i];
+ }
+ else
+ screen = screens[0];
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)screens);
+ xf86removeScreen(XF86Config, screen);
+ return (0);
+ }
+ if (i < nlist - 2)
+ screen = screens[i];
+ }
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)screens);
+
+ if (screen == NULL) {
+ char label[256];
+ XF86ConfDevicePtr *devices = NULL;
+ XF86ConfMonitorPtr *monitors = NULL;
+
+ device = XF86Config->conf_device_lst;
+ monitor = XF86Config->conf_monitor_lst;
+
+ if (device == NULL || monitor == NULL) {
+ ClearScreen();
+ refresh();
+ Dialog("Configuration error",
+ "You need to configure (at least) one card and one "
+ "monitor before creating a screen definition.",
+ 9, 50, " Ok ", NULL, 0);
+
+ return (-1);
+ }
+
+ XmuSnprintf(label, sizeof(label), "Screen%d", nlist ? nlist - 2 : 0);
+ ClearScreen();
+ refresh();
+ identifier =
+ DialogInput("Screen identifier",
+ "Enter an identifier for your screen definition:",
+ 11, 40, label,
+ " Next >>", " Cancel ", 0);
+ if (identifier == NULL)
+ return (-1);
+
+ nlist = 0;
+ list = NULL;
+ while (device) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
+ list[nlist] = XtNewString(device->dev_identifier);
+ devices = (XF86ConfDevicePtr*)XtRealloc((XtPointer)devices, (nlist + 1) *
+ sizeof(XF86ConfDevicePtr));
+ devices[nlist] = device;
+ ++nlist;
+ device = (XF86ConfDevicePtr)(device->list.next);
+ }
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Screen card", "Please select a video card:",
+ 13, 60, 4, nlist, list, " Next >>", " Cancel ", 0);
+ for (def = 0; def < nlist; def++)
+ XtFree(list[def]);
+ XtFree((XtPointer)list);
+ if (i < 0) {
+ XtFree(identifier);
+ XtFree((XtPointer)devices);
+ return (-1);
+ }
+ device = devices[i];
+ XtFree((XtPointer)devices);
+
+ nlist = 0;
+ list = NULL;
+ while (monitor) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
+ list[nlist] = XtNewString(monitor->mon_identifier);
+ monitors = (XF86ConfMonitorPtr*)XtRealloc((XtPointer)monitors, (nlist + 1) *
+ sizeof(XF86ConfMonitorPtr));
+ monitors[nlist] = monitor;
+ ++nlist;
+ monitor = (XF86ConfMonitorPtr)(monitor->list.next);
+ }
+ XmuSnprintf(label, sizeof(label),
+ "Select the monitor connected to \"%s\":",
+ device->dev_identifier);
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Screen monitor", label,
+ 13, 60, 4, nlist, list, " Next >>", " Cancel ", 0);
+ for (def = 0; def < nlist; def++)
+ XtFree(list[def]);
+ XtFree((XtPointer)list);
+ if (i < 0) {
+ XtFree(identifier);
+ XtFree((XtPointer)monitors);
+ return (-1);
+ }
+ monitor = monitors[i];
+ XtFree((XtPointer)monitors);
+
+ screen = (XF86ConfScreenPtr)XtCalloc(1, sizeof(XF86ConfScreenRec));
+ screen->scrn_device = device;
+ screen->scrn_monitor = monitor;
+ }
+
+ if (screen->scrn_defaultdepth == 1)
+ def = 0;
+ else if (screen->scrn_defaultdepth == 4)
+ def = 1;
+ else if (screen->scrn_defaultdepth == 8)
+ def = 2;
+ else if (screen->scrn_defaultdepth == 15)
+ def = 3;
+ else if (screen->scrn_defaultdepth == 16)
+ def = 4;
+ else if (screen->scrn_defaultdepth == 24)
+ def = 5;
+ else {
+ if (screen->scrn_device && screen->scrn_device->dev_driver &&
+ strcmp(screen->scrn_device->dev_driver, "vga") == 0)
+ def = 1; /* 4bpp */
+ else
+ def = 2; /* 8bpp */
+ }
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Screen depth",
+ "Please specify which color depth you want to use by default:",
+ 15, 60, 6, sizeof(depths) / sizeof(depths[0]), depths,
+ " Next >>", " Cancel ", def);
+ if (i < 0) {
+ if (screen->scrn_identifier == NULL) {
+ XtFree(identifier);
+ XtFree((XtPointer)screen);
+ }
+ return (-1);
+ }
+ else
+ /* XXX depths must begin with the depth number */
+ screen->scrn_defaultdepth = atoi(depths[i]);
+
+ def = 0; /* use def to count how many modes are selected*/
+ nlist = 0;
+ list = NULL;
+ checks = XtMalloc(sizeof(modes) / sizeof(modes[0]));
+ /* XXX list fields in the code below are not allocated */
+ disp_allocated = 0;
+ display = screen->scrn_display_lst;
+ while (display && display->disp_depth != screen->scrn_defaultdepth)
+ display = (XF86ConfDisplayPtr)(display->list.next);
+ if (display == NULL) {
+ display = (XF86ConfDisplayPtr)XtCalloc(1, sizeof(XF86ConfDisplayRec));
+ display->disp_white.red = display->disp_black.red = -1;
+ display->disp_depth = screen->scrn_defaultdepth;
+ disp_allocated = 1;
+ }
+ else {
+ mode = display->disp_mode_lst;
+ while (mode) {
+ for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++)
+ if (strcmp(modes[i], mode->mode_name) == 0) {
+ break;
+ }
+
+ if (i == sizeof(modes) / sizeof(modes[0])) {
+ list = (char**)XtRealloc((XtPointer)list,
+ (nlist + 1) * sizeof(char*));
+ list[nlist] = mode->mode_name;
+ checks = XtRealloc(checks, sizeof(modes) / sizeof(modes[0]) +
+ nlist + 1);
+ checks[nlist] = 1;
+ ++def;
+ nlist++;
+ break;
+ }
+ mode = (XF86ModePtr)(mode->list.next);
+ }
+ }
+
+ for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++)
+ checks[i + nlist] = 0;
+
+ mode = display->disp_mode_lst;
+ while (mode) {
+ for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++)
+ if (strcmp(modes[i], mode->mode_name) == 0) {
+ ++def;
+ checks[i + nlist] = 1;
+ break;
+ }
+ mode = (XF86ModePtr)(mode->list.next);
+ }
+
+ if (nlist == 0 && def == 0)
+ checks[7] = 1; /* 640x480 */
+ list = (char**)XtRealloc((XtPointer)list, (nlist + sizeof(modes) /
+ sizeof(modes[0])) * sizeof(char*));
+ for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++)
+ list[i + nlist] = modes[i];
+ nlist += sizeof(modes) / sizeof(modes[0]);
+
+ ClearScreen();
+ refresh();
+ i = DialogCheckBox("Screen modes",
+ "Select the video modes for this screen:",
+ 17, 60, 8, sizeof(modes) / sizeof(modes[0]), modes,
+ " Finish ", " Cancel ", checks);
+ if (i < 0) {
+ if (screen->scrn_identifier == NULL) {
+ XtFree(identifier);
+ XtFree((XtPointer)screen);
+ XtFree((XtPointer)list);
+ if (disp_allocated)
+ XtFree((XtPointer)display);
+ }
+ return (-1);
+ }
+
+ mode = display->disp_mode_lst;
+ while (mode) {
+ ptr = (XF86ModePtr)(mode->list.next);
+ XtFree(mode->mode_name);
+ XtFree((XtPointer)mode);
+ mode = ptr;
+ }
+ display->disp_mode_lst = NULL;
+
+ for (i = 0; i < nlist; i++) {
+ if (checks[i]) {
+ mode = (XF86ModePtr)XtCalloc(1, sizeof(XF86ModeRec));
+ mode->mode_name = XtNewString(list[i]);
+ if (display->disp_mode_lst == NULL)
+ display->disp_mode_lst = ptr = mode;
+ else {
+ ptr->list.next = mode;
+ ptr = mode;
+ }
+ }
+ }
+ XtFree((XtPointer)list);
+
+ if (disp_allocated) {
+ display->list.next = NULL;
+ if (screen->scrn_display_lst == NULL)
+ screen->scrn_display_lst = display;
+ else
+ screen->scrn_display_lst->list.next = display;
+ }
+
+ if (screen->scrn_identifier == NULL) {
+ screen->scrn_identifier = identifier;
+ screen->scrn_monitor_str = XtNewString(monitor->mon_identifier);
+ screen->scrn_device_str = XtNewString(device->dev_identifier);
+ XF86Config->conf_screen_lst =
+ xf86addScreen(XF86Config->conf_screen_lst, screen);
+ }
+
+ return (1);
+}
+
+static XF86ConfAdjacencyPtr
+CopyAdjacency(XF86ConfAdjacencyPtr ptr)
+{
+ XF86ConfAdjacencyPtr adj = (XF86ConfAdjacencyPtr)
+ XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
+
+ adj->adj_scrnum = ptr->adj_scrnum;
+ adj->adj_screen = ptr->adj_screen;
+ adj->adj_screen_str = XtNewString(ptr->adj_screen_str);
+ adj->adj_top = ptr->adj_top;
+ if (ptr->adj_top_str)
+ adj->adj_top_str = XtNewString(ptr->adj_top_str);
+ adj->adj_bottom = ptr->adj_bottom;
+ if (ptr->adj_bottom_str)
+ adj->adj_bottom_str = XtNewString(ptr->adj_bottom_str);
+ adj->adj_left = ptr->adj_left;
+ if (ptr->adj_left_str)
+ adj->adj_left_str = XtNewString(ptr->adj_left_str);
+ adj->adj_right = ptr->adj_right;
+ if (ptr->adj_right_str)
+ adj->adj_right_str = XtNewString(ptr->adj_right_str);
+ adj->adj_where = ptr->adj_where;
+ adj->adj_x = ptr->adj_x;
+ adj->adj_y = ptr->adj_y;
+ if (ptr->adj_refscreen)
+ adj->adj_refscreen = XtNewString(ptr->adj_refscreen);
+
+ return (adj);
+}
+
+static XF86ConfInactivePtr
+CopyInactive(XF86ConfInactivePtr ptr)
+{
+ XF86ConfInactivePtr inac = (XF86ConfInactivePtr)
+ XtCalloc(1, sizeof(XF86ConfInactiveRec));
+
+ inac->inactive_device = ptr->inactive_device;
+ if (ptr->inactive_device_str)
+ inac->inactive_device_str = XtNewString(ptr->inactive_device_str);
+
+ return (inac);
+}
+
+static XF86ConfInputrefPtr
+CopyInputref(XF86ConfInputrefPtr ptr)
+{
+ XF86ConfInputrefPtr iref = (XF86ConfInputrefPtr)
+ XtCalloc(1, sizeof(XF86ConfInputrefRec));
+ XF86OptionPtr opt = ptr->iref_option_lst;
+
+ iref->iref_inputdev = ptr->iref_inputdev;
+ if (ptr->iref_inputdev_str)
+ iref->iref_inputdev_str = XtNewString(ptr->iref_inputdev_str);
+ while (opt) {
+ iref->iref_option_lst = xf86addNewOption(iref->iref_option_lst,
+ XtNewString(opt->opt_name),
+ opt->opt_val ? XtNewString(opt->opt_val) : NULL);
+ opt = (XF86OptionPtr)(opt->list.next);
+ }
+
+ return (iref);
+}
+
+static XF86ConfLayoutPtr
+CopyLayout(XF86ConfLayoutPtr ptr)
+{
+ XF86ConfLayoutPtr lay = (XF86ConfLayoutPtr)
+ XtCalloc(1, sizeof(XF86ConfLayoutRec));
+ XF86ConfAdjacencyPtr adj = ptr->lay_adjacency_lst, padj;
+ XF86ConfInactivePtr inac = ptr->lay_inactive_lst, pinac;
+ XF86ConfInputrefPtr iref = ptr->lay_input_lst, piref;
+ XF86OptionPtr opt = ptr->lay_option_lst;
+
+ if (ptr->lay_identifier)
+ lay->lay_identifier = XtNewString(ptr->lay_identifier);
+ if (adj) {
+ padj = lay->lay_adjacency_lst = CopyAdjacency(adj);
+ adj = (XF86ConfAdjacencyPtr)(adj->list.next);
+ while (adj) {
+ padj->list.next = CopyAdjacency(adj);
+ padj = (XF86ConfAdjacencyPtr)(padj->list.next);
+ adj = (XF86ConfAdjacencyPtr)(adj->list.next);
+ }
+ }
+ if (inac) {
+ pinac = lay->lay_inactive_lst = CopyInactive(inac);
+ inac = (XF86ConfInactivePtr)(inac->list.next);
+ while (inac) {
+ pinac->list.next = CopyInactive(inac);
+ pinac = (XF86ConfInactivePtr)(pinac->list.next);
+ inac = (XF86ConfInactivePtr)(inac->list.next);
+ }
+ }
+ if (iref) {
+ piref = lay->lay_input_lst = CopyInputref(iref);
+ iref = (XF86ConfInputrefPtr)(iref->list.next);
+ while (iref) {
+ piref->list.next = CopyInputref(iref);
+ piref = (XF86ConfInputrefPtr)(piref->list.next);
+ iref = (XF86ConfInputrefPtr)(iref->list.next);
+ }
+ }
+
+ while (opt) {
+ lay->lay_option_lst = xf86addNewOption(lay->lay_option_lst,
+ XtNewString(opt->opt_name),
+ opt->opt_val ? XtNewString(opt->opt_val) : NULL);
+ opt = (XF86OptionPtr)(opt->list.next);
+ }
+
+ return (lay);
+}
+
+static void
+FreeLayout(XF86ConfLayoutPtr lay)
+{
+ static XF86ConfigRec xf86config;
+
+ xf86config.conf_layout_lst = lay;
+ xf86removeLayout(&xf86config, lay);
+}
+
+static int
+LayoutConfig(void)
+{
+ int i;
+ XF86ConfLayoutPtr *layouts = NULL, rlayout = NULL,
+ layout = XF86Config->conf_layout_lst;
+ XF86ConfInputPtr input = XF86Config->conf_input_lst;
+ char **list = NULL, *identifier = NULL;
+ XF86ConfInputPtr *mouses = NULL, *keyboards = NULL, mouse, keyboard;
+ XF86ConfInputrefPtr iref, piref, mref, kref;
+ XF86ConfAdjacencyPtr adj, padj;
+ int nmouses, nkeyboards;
+ int nlist;
+ XF86OptionPtr option;
+ XF86ConfScreenPtr screen, *screens;
+
+ nmouses = nkeyboards = 0;
+ while (input) {
+ if (strcmp(input->inp_driver, "mouse") == 0) {
+ mouses = (XF86ConfInputPtr*)XtRealloc((XtPointer)mouses,
+ (nmouses + 1) * sizeof(XF86ConfInputPtr));
+ mouses[nmouses] = input;
+ ++nmouses;
+ }
+ else if (strcmp(input->inp_driver, "keyboard") == 0) {
+ keyboards = (XF86ConfInputPtr*)XtRealloc((XtPointer)keyboards,
+ (nkeyboards + 1) * sizeof(XF86ConfInputPtr));
+ keyboards[nkeyboards] = input;
+ ++nkeyboards;
+ }
+ input = (XF86ConfInputPtr)(input->list.next);
+ }
+ if (XF86Config->conf_screen_lst == NULL ||
+ nmouses == 0 || nkeyboards == 0) {
+ XtFree((XtPointer)mouses);
+ XtFree((XtPointer)keyboards);
+ ClearScreen();
+ refresh();
+ Dialog("Configuration error",
+ "You need to configure (at least) one screen, mouse "
+ "and keyboard before creating a layout definition.",
+ 9, 50, " Ok ", NULL, 0);
+ return (-1);
+ }
+
+ nlist = 0;
+ while (layout) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
+ list[nlist] = XtMalloc(sizeof(Edit) +
+ strlen(layout->lay_identifier) + 1);
+ sprintf(list[nlist], "%s%s", Edit, layout->lay_identifier);
+ layouts = (XF86ConfLayoutPtr*)XtRealloc((XtPointer)layouts, (nlist + 1) *
+ sizeof(XF86ConfLayoutPtr));
+ layouts[nlist] = layout;
+ ++nlist;
+ layout = (XF86ConfLayoutPtr)(layout->list.next);
+ }
+
+ layout = NULL;
+
+ if (nlist) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
+ list[nlist++] = XtNewString("Add new layout");
+ if (nlist == 2) {
+ i = strlen("Remove ") + strlen(layouts[0]->lay_identifier) + 1;
+ list[nlist] = XtMalloc(i);
+ XmuSnprintf(list[nlist], i, "Remove %s", layouts[0]->lay_identifier);
+ ++nlist;
+ }
+ else
+ list[nlist++] = XtNewString("Remove layout");
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Layout configuration",
+ "You can edit or remove a previously configured "
+ "layout, or add a new one.", 14, 60, 4, nlist, list,
+ " Ok ", " Cancel ", 0);
+ if (i < 0) {
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)layouts);
+ XtFree((XtPointer)mouses);
+ XtFree((XtPointer)keyboards);
+ return (-1);
+ }
+ if (nlist > 2 && i == nlist - 1) {
+ if (nlist > 3) {
+ for (i = 0; i < nlist - 2; i++) {
+ /* XXX Remove the "Edit " from list entries */
+ memmove(list[i], list[i] + sizeof(Edit) - 1,
+ strlen(list[i]) - sizeof(Edit) + 2);
+ }
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Remove layout",
+ "Select which layout to remove",
+ 13, 60, 4, nlist - 2, list,
+ " Remove ", " Cancel ", 0);
+ if (i < 0) {
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)layouts);
+ XtFree((XtPointer)mouses);
+ XtFree((XtPointer)keyboards);
+ return (-1);
+ }
+ layout = layouts[i];
+ }
+ else
+ layout = layouts[0];
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)layouts);
+ XtFree((XtPointer)mouses);
+ XtFree((XtPointer)keyboards);
+ xf86removeLayout(XF86Config, layout);
+ return (0);
+ }
+ if (i < nlist - 2)
+ layout = layouts[i];
+ }
+ for (i = 0; i < nlist; i++)
+ XtFree(list[i]);
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)layouts);
+
+ if (layout == NULL) {
+ char label[32];
+
+ layout = (XF86ConfLayoutPtr)XtCalloc(1, sizeof(XF86ConfLayoutRec));
+ XmuSnprintf(label, sizeof(label), "Layout%d", nlist ? nlist - 2 : 0);
+ ClearScreen();
+ refresh();
+ identifier =
+ DialogInput("Layout identifier",
+ "Enter an identifier for your layout definition:",
+ 11, 40, label,
+ " Next >>", " Cancel ", 0);
+ if (identifier == NULL) {
+ XtFree((XtPointer)layout);
+ XtFree((XtPointer)mouses);
+ XtFree((XtPointer)keyboards);
+ return (-1);
+ }
+ }
+ else {
+ /* So that we can safely change it */
+ rlayout = layout;
+ layout = CopyLayout(rlayout);
+ }
+
+
+ mouse = keyboard = NULL;
+
+ /* Mouse */
+ piref = NULL;
+ iref = layout->lay_input_lst;
+ while (iref) {
+ if (strcmp(iref->iref_inputdev->inp_driver, "mouse") == 0) {
+ if (mouse == NULL)
+ piref = iref;
+ if (xf86findOption(iref->iref_option_lst, "CorePointer")) {
+ mouse = iref->iref_inputdev;
+ piref = iref;
+ break;
+ }
+ }
+ iref = (XF86ConfInputrefPtr)(iref->list.next);
+ }
+ if (mouse == NULL) {
+ if (piref) {
+ mref = piref;
+ mouse = piref->iref_inputdev;
+ piref->iref_option_lst =
+ xf86addNewOption(piref->iref_option_lst,
+ XtNewString("CorePointer"), NULL);
+ }
+ else {
+ mouse = mouses[0];
+ mref = iref = (XF86ConfInputrefPtr)XtCalloc(1, sizeof(XF86ConfInputrefRec));
+ iref->iref_inputdev_str = XtNewString(mouse->inp_identifier);
+ iref->iref_inputdev = mouse;
+ iref->iref_option_lst =
+ xf86addNewOption(iref->iref_option_lst,
+ XtNewString("CorePointer"), NULL);
+ iref->list.next = layout->lay_input_lst;
+ if (layout->lay_input_lst == NULL)
+ layout->lay_input_lst = iref;
+ else {
+ iref->list.next = layout->lay_input_lst;
+ layout->lay_input_lst = iref;
+ }
+ }
+ }
+ else
+ mref = piref;
+
+ /* XXX list fields are not allocated */
+ if (nmouses > 1) {
+ nlist = 0;
+ list = (char**)XtMalloc(sizeof(char*));
+ list[nlist++] = mouse->inp_identifier;
+ input = XF86Config->conf_input_lst;
+ while (input) {
+ if (input != mouse && strcmp(input->inp_driver, "mouse") == 0) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
+ list[nlist++] = input->inp_identifier;
+ }
+ input = (XF86ConfInputPtr)(input->list.next);
+ }
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Select Core Pointer",
+ "Select the mouse connected to you computer",
+ 12, 60, 4, nlist, list, " Ok ", " Cancel ", 0);
+ if (i < 0) {
+ XtFree((XtPointer)mouses);
+ XtFree((XtPointer)keyboards);
+ XtFree((XtPointer)list);
+ if (layout->lay_identifier == NULL)
+ XtFree(identifier);
+ FreeLayout(layout);
+ return (-1);
+ }
+ if (i > 0) {
+ /* Did not select the default one */
+ iref = layout->lay_input_lst;
+ while (iref) {
+ if (strcasecmp(iref->iref_inputdev_str, list[i]) == 0) {
+ if ((option = xf86findOption(iref->iref_option_lst,
+ "SendCoreEvents")) != NULL) {
+ XtFree(option->opt_name);
+ option->opt_name = XtNewString("CorePointer");
+ }
+ else
+ iref->iref_option_lst =
+ xf86addNewOption(iref->iref_option_lst,
+ "CorePointer", NULL);
+ option = xf86findOption(mref->iref_option_lst,
+ "CorePointer");
+ XtFree(option->opt_name);
+ option->opt_name = XtNewString("SendCoreEvents");
+ break;
+ }
+ iref = (XF86ConfInputrefPtr)(iref->list.next);
+ }
+ }
+
+ /* XXX Write code to add/remove more mouses here */
+ }
+
+
+ /* Keyboard */
+ piref = NULL;
+ iref = layout->lay_input_lst;
+ while (iref) {
+ if (strcmp(iref->iref_inputdev->inp_driver, "keyboard") == 0) {
+ if (keyboard == NULL)
+ piref = iref;
+ if (xf86findOption(iref->iref_option_lst, "CoreKeyboard")) {
+ keyboard = iref->iref_inputdev;
+ piref = iref;
+ break;
+ }
+ }
+ iref = (XF86ConfInputrefPtr)(iref->list.next);
+ }
+ if (keyboard == NULL) {
+ if (piref) {
+ kref = piref;
+ keyboard = piref->iref_inputdev;
+ piref->iref_option_lst =
+ xf86addNewOption(piref->iref_option_lst,
+ XtNewString("CoreKeyboard"), NULL);
+ }
+ else {
+ keyboard = keyboards[0];
+ kref = iref = (XF86ConfInputrefPtr)XtCalloc(1, sizeof(XF86ConfInputrefRec));
+ iref->iref_inputdev_str = XtNewString(keyboard->inp_identifier);
+ iref->iref_inputdev = keyboard;
+ iref->iref_option_lst =
+ xf86addNewOption(iref->iref_option_lst,
+ XtNewString("CoreKeyboard"), NULL);
+ iref->list.next = layout->lay_input_lst;
+ if (layout->lay_input_lst == NULL)
+ layout->lay_input_lst = iref;
+ else {
+ iref->list.next = layout->lay_input_lst;
+ layout->lay_input_lst = iref;
+ }
+ }
+ }
+ else
+ kref = piref;
+
+ /* XXX list fields are not allocated */
+ if (nkeyboards > 1) {
+ nlist = 0;
+ list = (char**)XtMalloc(sizeof(char*));
+ list[nlist++] = keyboard->inp_identifier;
+ input = XF86Config->conf_input_lst;
+ while (input) {
+ if (input != keyboard && strcmp(input->inp_driver, "keyboard") == 0) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
+ list[nlist++] = input->inp_identifier;
+ }
+ input = (XF86ConfInputPtr)(input->list.next);
+ }
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Select Core Keyboard",
+ "Select the keyboard connected to you computer",
+ 12, 60, 4, nlist, list, " Ok ", " Cancel ", 0);
+ if (i < 0) {
+ XtFree((XtPointer)mouses);
+ XtFree((XtPointer)keyboards);
+ XtFree((XtPointer)list);
+ if (layout->lay_identifier == NULL)
+ XtFree(identifier);
+ FreeLayout(layout);
+ return (-1);
+ }
+ if (i > 0) {
+ /* Did not select the default one */
+ iref = layout->lay_input_lst;
+ while (iref) {
+ if (strcasecmp(iref->iref_inputdev_str, list[i]) == 0) {
+ if ((option = xf86findOption(iref->iref_option_lst,
+ "SendCoreEvents")) != NULL) {
+ XtFree(option->opt_name);
+ option->opt_name = XtNewString("CoreKeyboard");
+ }
+ else
+ iref->iref_option_lst =
+ xf86addNewOption(iref->iref_option_lst,
+ "CoreKeyboard", NULL);
+ option = xf86findOption(kref->iref_option_lst,
+ "CoreKeyboard");
+ XtFree(option->opt_name);
+ option->opt_name = XtNewString("SendCoreEvents");
+ break;
+ }
+ iref = (XF86ConfInputrefPtr)(iref->list.next);
+ }
+ }
+
+ /* XXX Write code to add/remove more keyboards here */
+ }
+
+ XtFree((XtPointer)mouses);
+ XtFree((XtPointer)keyboards);
+
+ /* Just one screen */
+ if (XF86Config->conf_screen_lst->list.next == NULL) {
+ ClearScreen();
+ refresh();
+ Dialog("Layout configuration",
+ (nmouses > 1 || nkeyboards > 1) ?
+ "As you have only one screen configured, I can now finish "
+ "creating this Layout configuration."
+ :
+ "As you have only one screen, mouse and keyboard configured, "
+ "I can now finish creating this Layout configuration.",
+ 12, 60, " Finish ", NULL, 0);
+
+ goto LayoutFinish;
+ }
+
+
+ /* The code below just adds a screen to the right of the last
+ * one, or allows removing a screen.
+ * Needs some review, and adding more options.
+ */
+
+ /*CONSTCOND*/
+ while (1) {
+ static char *screen_opts[] = {
+ "Add a new screen to layout",
+ "Remove screen from layout",
+ "Finish layout configuration",
+ };
+
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Layout configuration", "Please choose one option:",
+ 12, 60, 3, sizeof(screen_opts) / sizeof(screen_opts[0]),
+ screen_opts, " Done ", " Cancel all changes ", 2);
+
+ /* cancel */
+ if (i < 0) {
+ XtFree(identifier);
+ FreeLayout(layout);
+ return (-1);
+ }
+
+ /* add new screen */
+ else if (i == 0) {
+ nlist = 0;
+ list = NULL;
+ screens = NULL;
+ screen = XF86Config->conf_screen_lst;
+ while (screen) {
+ adj = layout->lay_adjacency_lst;
+ while (adj) {
+ if (adj->adj_screen == screen)
+ break;
+ adj = (XF86ConfAdjacencyPtr)(adj->list.next);
+ }
+ if (adj == NULL) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
+ screens = (XF86ConfScreenPtr*)XtRealloc((XtPointer)screens,
+ (nlist + 1) * sizeof(XF86ConfScreenPtr));
+ /* NOT duplicated */
+ list[nlist] = screen->scrn_identifier;
+ screens[nlist] = screen;
+ ++nlist;
+ }
+ screen = (XF86ConfScreenPtr)(screen->list.next);
+ }
+
+ if (nlist == 0)
+ continue;
+
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Layout add screen", "Choose screen to add:",
+ 12, 60, 3, nlist, list,
+ " Add ", " Cancel ", 0);
+ if (i >= 0) {
+ padj = layout->lay_adjacency_lst;
+ adj = (XF86ConfAdjacencyPtr)
+ XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
+ adj->adj_screen = screens[i];
+ if (padj == NULL) {
+ adj->adj_where = CONF_ADJ_ABSOLUTE;
+ layout->lay_adjacency_lst = adj;
+ }
+ else {
+ while (padj->list.next)
+ padj = (XF86ConfAdjacencyPtr)(padj->list.next);
+ padj->list.next = adj;
+ adj->adj_where = CONF_ADJ_RIGHTOF;
+ adj->adj_refscreen =
+ XtNewString(padj->adj_screen->scrn_identifier);
+ }
+ }
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)screens);
+ }
+
+ /* remove a screen */
+ else if (i == 1) {
+ nlist = 0;
+ list = NULL;
+ screens = NULL;
+ adj = layout->lay_adjacency_lst;
+
+ while (adj) {
+ list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
+ screens = (XF86ConfScreenPtr*)XtRealloc((XtPointer)screens,
+ (nlist + 1) * sizeof(XF86ConfScreenPtr));
+ list[nlist] = adj->adj_screen->scrn_identifier;
+ screens[nlist] = adj->adj_screen;
+ ++nlist;
+ adj = (XF86ConfAdjacencyPtr)(adj->list.next);
+ }
+
+ if (nlist == 0)
+ continue;
+
+ ClearScreen();
+ refresh();
+ i = DialogMenu("Layout remove screen", "Choose screen to remove:",
+ 12, 60, 3, nlist, list,
+ " Remove ", " Cancel ", 0);
+
+ adj = padj = layout->lay_adjacency_lst;
+ while (adj) {
+ if (adj->adj_screen == screens[i]) {
+ padj = (XF86ConfAdjacencyPtr)(padj->list.next);
+ if (padj && adj->adj_where == CONF_ADJ_RIGHTOF &&
+ padj->adj_where == CONF_ADJ_RIGHTOF) {
+ XtFree(padj->adj_refscreen);
+ padj->adj_refscreen = XtNewString(adj->adj_refscreen);
+ }
+ xf86removeAdjacency(layout, adj);
+ break;
+ }
+ padj = adj;
+ adj = (XF86ConfAdjacencyPtr)(padj->list.next);
+ }
+ XtFree((XtPointer)list);
+ XtFree((XtPointer)screens);
+ }
+
+ /* finish screen configuration */
+ else
+ break;
+ }
+
+LayoutFinish:
+ if (layout->lay_adjacency_lst == NULL) {
+ adj = (XF86ConfAdjacencyPtr)XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
+ adj->adj_screen = XF86Config->conf_screen_lst;
+ adj->adj_screen_str = XtNewString(XF86Config->conf_screen_lst->scrn_identifier);
+ adj->adj_where = CONF_ADJ_ABSOLUTE;
+ layout->lay_adjacency_lst = adj;
+ }
+ if (rlayout) {
+ /* just edited this layout */
+ if (nmouses > 1 || nkeyboards > 1) {
+ XF86ConfAdjacencyPtr tadj = rlayout->lay_adjacency_lst;
+ XF86ConfInactivePtr tinac = rlayout->lay_inactive_lst;
+ XF86ConfInputrefPtr tinp = rlayout->lay_input_lst;
+
+ rlayout->lay_adjacency_lst = layout->lay_adjacency_lst;
+ rlayout->lay_inactive_lst = layout->lay_inactive_lst;
+ rlayout->lay_input_lst = layout->lay_input_lst;
+
+ layout->lay_adjacency_lst = tadj;
+ layout->lay_inactive_lst = tinac;
+ layout->lay_input_lst = tinp;
+ FreeLayout(layout);
+ }
+ return (0);
+ }
+ else {
+ layout->lay_identifier = identifier;
+ XF86Config->conf_layout_lst =
+ xf86addLayout(XF86Config->conf_layout_lst, layout);
+ }
+
+ return (1);
+}
+
+static void
+ClearScreen(void)
+{
+ int i, j;
+
+ wattrset(stdscr, screen_attr);
+ for (i = 0; i < LINES; i++) {
+ wmove(stdscr, i, 0);
+ for (j = 0; j < COLS; j++)
+ waddch(stdscr, ACS_PLUS);
+ }
+ touchwin(stdscr);
+}
+
+static int
+Dialog(char *title, char * prompt, int height, int width,
+ char *label1, char *label2, int button)
+{
+ int x, x1, x2, y, key, l1len, l2len;
+ WINDOW *dialog;
+
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+ dialog = newwin(height, width, y, x);
+ keypad(dialog, TRUE);
+
+ PaintWindow(dialog, title, 0, 0, height, width);
+ wattrset(dialog, dialog_attr);
+ PrintWrap(dialog, prompt, width - 3, 2, 3);
+
+ l1len = strlen(label1);
+ if (label2)
+ l2len = strlen(label2);
+ else {
+ l2len = button = 0;
+ }
+
+ x1 = (width - (l1len + l2len)) / (label2 ? 3 : 2);
+ x2 = x1 + x1 + l1len;
+ y = height - 3;
+ if (!button) {
+ if (label2)
+ PaintButton(dialog, label2, y, x2, FALSE);
+ PaintButton(dialog, label1, y, x1, TRUE);
+ }
+ else {
+ PaintButton(dialog, label1, y, x1, FALSE);
+ if (label2)
+ PaintButton(dialog, label2, y, x2, TRUE);
+ }
+ wrefresh(dialog);
+
+ /*CONSTCOND*/
+ while (1) {
+ key = wgetch(dialog);
+ switch (key) {
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ if (!button) {
+ if (label2) {
+ button = 1;
+ PaintButton(dialog, label1, y, x1, FALSE);
+ PaintButton(dialog, label2, y, x2, TRUE);
+ }
+
+ }
+ else {
+ if (label2) {
+ button = 0;
+ PaintButton(dialog, label2, y, x2, FALSE);
+ PaintButton(dialog, label1, y, x1, TRUE);
+ }
+ }
+ wrefresh(dialog);
+ break;
+ case ' ':
+ case '\r':
+ case '\n':
+ delwin(dialog);
+ return button;
+ }
+ }
+ /*NOTREACHED*/
+}
+
+static void
+PaintWindow(WINDOW *win, char *title_str, int y, int x, int height, int width)
+{
+ int i, j;
+
+ if (title_str != NULL) {
+ j = (width - strlen(title_str)) / 2 - 1;
+
+ wattrset(win, title_attr);
+ wmove(win, x, y);
+ for (i = 0; i < j; i++)
+ waddch(win, ' ');
+ waddstr(win, title_str);
+ for (; i < width; i++)
+ waddch(win, ' ');
+ }
+
+ wattrset(win, 0);
+
+ for (i = 1; i < height; i++) {
+ wmove(win, y + i, x);
+ for (j = 0; j < width; j++)
+ if (i == height - 1 && !j)
+ waddch(win, highlight_border_attr | ACS_LLCORNER);
+ else if (i == height - 1 && j == width - 1)
+ waddch(win, shadow_border_attr | ACS_LRCORNER);
+ else if (i == height - 1)
+ waddch(win, shadow_border_attr | ACS_HLINE);
+ else if (!j)
+ waddch(win, highlight_border_attr | ACS_VLINE);
+ else if (j == width - 1)
+ waddch(win, shadow_border_attr | ACS_VLINE);
+ else
+ waddch(win, dialog_attr | ' ');
+ }
+
+}
+
+static void
+PaintBox(WINDOW *win, int y, int x, int height, int width)
+{
+ int i, j;
+
+ wattrset(win, 0);
+
+ for (i = 0; i < height; i++) {
+ wmove(win, y + i, x);
+ for (j = 0; j < width; j++)
+ if (!i && !j)
+ waddch(win, shadow_border_attr | ACS_ULCORNER);
+ else if (i == height - 1 && !j)
+ waddch(win, shadow_border_attr | ACS_LLCORNER);
+ else if (!i && j == width-1)
+ waddch(win, highlight_border_attr | ACS_URCORNER);
+ else if (i == height - 1 && j == width - 1)
+ waddch(win, highlight_border_attr | ACS_LRCORNER);
+ else if (!i)
+ waddch(win, shadow_border_attr | ACS_HLINE);
+ else if (i == height - 1)
+ waddch(win, highlight_border_attr | ACS_HLINE);
+ else if (!j)
+ waddch(win, shadow_border_attr | ACS_VLINE);
+ else if (j == width - 1)
+ waddch(win, highlight_border_attr | ACS_VLINE);
+ else
+ waddch(win, dialog_attr | ' ');
+ }
+
+}
+
+static void
+PaintButton(WINDOW *win, char *label, int y, int x, int selected)
+{
+ int i, temp;
+
+ wmove(win, y, x);
+ wattrset(win, selected ? button_active_attr : button_inactive_attr);
+ waddstr(win, selected ? "[" : " ");
+ temp = strspn(label, " ");
+ label += temp;
+ wattrset(win, selected ? button_active_attr : button_inactive_attr);
+ for (i = 0; i < temp; i++)
+ waddch(win, ' ');
+ wattrset(win, selected ? button_active_attr : button_inactive_attr);
+ waddch(win, label[0]);
+ wattrset(win, selected ? button_active_attr : button_inactive_attr);
+ waddstr(win, label + 1);
+ wattrset(win, selected ? button_active_attr : button_inactive_attr);
+ waddstr(win, selected ? "]" : " ");
+ wmove(win, y, x + temp + 1);
+}
+
+static void
+PrintWrap(WINDOW *win, char *prompt, int width, int y, int x)
+{
+ int cur_x, cur_y, len, yinc;
+ char *word, *tempstr = XtMalloc(strlen(prompt) + 1);
+
+ cur_x = x;
+ cur_y = y;
+
+ while (*prompt == '\n') {
+ ++cur_y;
+ ++prompt;
+ }
+
+ strcpy(tempstr, prompt);
+
+ for (word = strtok(tempstr, " \n"); word != NULL; word = strtok(NULL, " \n")) {
+ yinc = 0;
+ len = strlen(word);
+ while (prompt[word - tempstr + len + yinc] == '\n')
+ ++yinc;
+ if (cur_x + strlen(word) > width) {
+ cur_y++;
+ cur_x = x;
+ }
+ wmove(win, cur_y, cur_x);
+ waddstr(win, word);
+ getyx(win, cur_y, cur_x);
+ if (yinc) {
+ cur_y += yinc;
+ cur_x = x;
+ }
+ else
+ cur_x++;
+ }
+
+ free(tempstr);
+}
+
+static int
+DialogMenu(char *title, char *prompt, int height, int width, int menu_height,
+ int item_no, char **items, char *label1, char *label2, int choice)
+{
+ int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0,
+ scrlx = 0, max_choice, nscroll, max_scroll, x1, x2, l1len, l2len;
+ WINDOW *dialog, *menu;
+
+ max_choice = MIN(menu_height, item_no);
+ max_scroll = MAX(0, item_no - max_choice);
+
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+ dialog = newwin(height, width, y, x);
+ keypad(dialog, TRUE);
+
+ PaintWindow(dialog, title, 0, 0, height, width);
+
+ wattrset(dialog, dialog_attr);
+ PrintWrap(dialog, prompt, width - 3, 2, 3);
+
+ l1len = strlen(label1);
+ l2len = strlen(label2);
+
+ x1 = (width - (l1len + l2len)) / 3;
+ x2 = x1 + x1 + l1len;
+
+ menu_width = width - 6;
+ getyx(dialog, cur_y, cur_x);
+ box_y = cur_y + 1;
+ box_x = (width - menu_width) / 2 - 1;
+
+ menu = subwin(dialog, menu_height, menu_width, y + box_y + 1, x + box_x + 1);
+ keypad(menu, TRUE);
+
+ /* draw a box around the menu items */
+ PaintBox(dialog, box_y, box_x, menu_height + 2, menu_width + 2);
+
+ item_x = 3;
+
+ if (choice > menu_height) {
+ scrlx = MIN(max_scroll, choice);
+ choice -= scrlx;
+ }
+
+ for (i = 0; i < max_choice; i++)
+ PaintItem(menu, items[i + scrlx], i, i == choice);
+ PaintScroller(menu, scrlx + choice, item_no, menu_height);
+ wnoutrefresh(menu);
+
+ x = width / 2 - 11;
+ y = height - 3;
+ PaintButton(dialog, label2, y, x2, FALSE);
+ PaintButton(dialog, label1, y, x1, TRUE);
+ wrefresh(dialog);
+
+ /*CONSTCOND*/
+ while (1) {
+ i = choice;
+ key = wgetch(dialog);
+
+ if (menu_height > 1 && key == KEY_PPAGE) {
+ if (!choice) {
+ if (scrlx) {
+ /* Scroll menu down */
+ getyx(dialog, cur_y, cur_x);
+
+ nscroll = max_choice > scrlx ? -scrlx : -max_choice;
+ scrollok(menu, TRUE);
+ wscrl(menu, nscroll);
+ scrollok(menu, FALSE);
+
+ PaintItem(menu, items[i = scrlx + nscroll], 0, TRUE);
+ for (++i; i <= scrlx; i++)
+ PaintItem(menu, items[i], i - (scrlx + nscroll), FALSE);
+ scrlx += nscroll;
+ PaintScroller(menu, scrlx + choice, item_no, menu_height);
+ wnoutrefresh(menu);
+ wrefresh(dialog);
+ continue;
+ }
+ }
+ i = 0;
+ }
+ else if (menu_height > 1 && key == KEY_NPAGE) {
+ if (choice == max_choice - 1) {
+ if (scrlx < max_scroll) {
+ /* Scroll menu up */
+ getyx(dialog, cur_y, cur_x);
+
+ nscroll = (scrlx + max_choice > max_scroll ?
+ max_scroll : scrlx + max_choice) - scrlx;
+ scrollok(menu, TRUE);
+ wscrl(menu, nscroll);
+ scrollok(menu, FALSE);
+
+ scrlx += nscroll;
+ for (i = 0; i < max_choice - 1; i++)
+ PaintItem(menu, items[i + scrlx], i, FALSE);
+ PaintItem(menu, items[i + scrlx], max_choice - 1, TRUE);
+ PaintScroller(menu, scrlx + choice, item_no, menu_height);
+ wnoutrefresh(menu);
+ wrefresh(dialog);
+ continue;
+ }
+ }
+ i = max_choice - 1;
+ }
+ else if (key == KEY_UP) {
+ if (!choice) {
+ if (scrlx) {
+ /* Scroll menu down */
+ getyx(dialog, cur_y, cur_x);
+ if (menu_height > 1) {
+ PaintItem(menu, items[scrlx], 0, FALSE);
+ scrollok(menu, TRUE);
+ wscrl(menu, - 1);
+ scrollok(menu, FALSE);
+ }
+ scrlx--;
+ PaintItem(menu, items[scrlx], 0, TRUE);
+ PaintScroller(menu, scrlx + choice, item_no, menu_height);
+ wnoutrefresh(menu);
+ wrefresh(dialog);
+ continue;
+ }
+ }
+ else
+ i = choice - 1;
+ }
+ else if (key == KEY_DOWN) {
+ if (choice == max_choice - 1) {
+ if (scrlx + choice < item_no - 1) {
+ /* Scroll menu up */
+ getyx(dialog, cur_y, cur_x);
+ if (menu_height > 1) {
+ PaintItem(menu, items[scrlx + max_choice - 1], max_choice - 1, FALSE);
+ scrollok(menu, TRUE);
+ scroll(menu);
+ scrollok(menu, FALSE);
+ }
+ scrlx++;
+ PaintItem(menu, items[scrlx + max_choice - 1], max_choice - 1, TRUE);
+ PaintScroller(menu, scrlx + choice, item_no, menu_height);
+ wnoutrefresh(menu);
+ wrefresh(dialog);
+ continue;
+ }
+ }
+ else
+ i = MIN(choice + 1, item_no - 1);
+ }
+
+ if (i != choice) {
+ getyx(dialog, cur_y, cur_x);
+ PaintItem(menu, items[scrlx + choice], choice, FALSE);
+
+ choice = i;
+ PaintItem(menu, items[scrlx + choice], choice, TRUE);
+ PaintScroller(menu, scrlx + choice, item_no, menu_height);
+ wnoutrefresh(menu);
+ wmove(dialog, cur_y, cur_x);
+ wrefresh(dialog);
+ continue;
+ }
+
+ switch (key) {
+ case TAB:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ if (!button) {
+ button = 1;
+ PaintButton(dialog, label1, y, x1, FALSE);
+ PaintButton(dialog, label2, y, x2, TRUE);
+ }
+ else {
+ button = 0;
+ PaintButton(dialog, label2, y, x2, FALSE);
+ PaintButton(dialog, label1, y, x1, TRUE);
+ }
+ wrefresh(dialog);
+ break;
+ case ' ':
+ case '\r':
+ case '\n':
+ delwin(dialog);
+ return (!button ? scrlx + choice : -1);
+ default:
+ for (i = scrlx + choice + 1; i < item_no; i++)
+ if (toupper(items[i][0]) == toupper(key))
+ break;
+ if (i == item_no) {
+ for (i = 0; i < scrlx + choice; i++)
+ if (toupper(items[i][0]) == toupper(key))
+ break;
+ }
+ getyx(dialog, cur_y, cur_x);
+ if (i < item_no && i != scrlx + choice) {
+ if (i >= scrlx && i < scrlx + max_choice) {
+ /* it is already visible */
+ PaintItem(menu, items[scrlx + choice], choice, FALSE);
+ choice = i - scrlx;
+ }
+ else {
+ scrlx = MIN(i, max_scroll);
+ choice = i - scrlx;
+ for (i = 0; i < max_choice; i++)
+ if (i != choice)
+ PaintItem(menu, items[scrlx + i], i, FALSE);
+ }
+ PaintItem(menu, items[scrlx + choice], choice, TRUE);
+ PaintScroller(menu, scrlx + choice, item_no, menu_height);
+ wnoutrefresh(menu);
+ wmove(dialog, cur_y, cur_x);
+ wrefresh(dialog);
+ }
+ break;
+ }
+ }
+ /*NOTREACHED*/
+}
+
+static void
+PaintItem(WINDOW *win, char *item, int choice, int selected)
+{
+ int i;
+
+ wattrset(win, selected ? title_attr : dialog_attr);
+ wmove(win, choice, 1);
+ for (i = 1; i < menu_width; i++)
+ waddch(win, ' ');
+ wmove(win, choice, item_x);
+ wattrset(win, selected ? title_attr : dialog_attr);
+ waddstr(win, item);
+}
+
+static void
+PaintScroller(WINDOW *win, int offset, int lenght, int visible)
+{
+ int i, pos;
+
+ if (lenght > visible)
+ pos = (visible / (double)lenght) * offset;
+ else
+ pos = offset;
+ wattrset(win, shadow_border_attr);
+ for (i = 0; i < visible; i++) {
+ wmove(win, i, 0);
+ waddch(win, i == pos ? ACS_BLOCK : ACS_VLINE);
+ }
+}
+
+static int
+DialogCheckBox(char *title, char *prompt, int height, int width, int menu_height,
+ int item_no, char **items, char *label1, char *label2, char *checks)
+{
+ int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
+ scrlx = 0, max_choice, nscroll, max_scroll, x1, x2, l1len, l2len;
+ WINDOW *dialog, *menu;
+
+ max_choice = MIN(menu_height, item_no);
+ max_scroll = MAX(0, item_no - max_choice);
+
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+ dialog = newwin(height, width, y, x);
+ keypad(dialog, TRUE);
+
+ PaintWindow(dialog, title, 0, 0, height, width);
+
+ wattrset(dialog, dialog_attr);
+ PrintWrap(dialog, prompt, width - 3, 2, 3);
+
+ l1len = strlen(label1);
+ l2len = strlen(label2);
+
+ x1 = (width - (l1len + l2len)) / 3;
+ x2 = x1 + x1 + l1len;
+
+ menu_width = width - 6;
+ getyx(dialog, cur_y, cur_x);
+ box_y = cur_y + 1;
+ box_x = (width - menu_width) / 2 - 1;
+
+ menu = subwin(dialog, menu_height, menu_width, y + box_y + 1, x + box_x + 1);
+ keypad(menu, TRUE);
+
+ /* draw a box around the menu items */
+ PaintBox(dialog, box_y, box_x, menu_height + 2, menu_width + 2);
+
+ item_x = 3;
+
+ for (i = 0; i < max_choice; i++)
+ PaintCheckItem(menu, items[i + scrlx], i, i == 0, checks[i + scrlx]);
+ PaintScroller(menu, scrlx + choice, item_no, menu_height);
+ wnoutrefresh(menu);
+
+ x = width / 2 - 11;
+ y = height - 3;
+ PaintButton(dialog, label2, y, x2, FALSE);
+ PaintButton(dialog, label1, y, x1, TRUE);
+ wrefresh(dialog);
+
+ /*CONSTCOND*/
+ while (1) {
+ i = choice;
+ key = wgetch(dialog);
+
+ if (menu_height > 1 && key == KEY_PPAGE) {
+ if (!choice) {
+ if (scrlx) {
+ /* Scroll menu down */
+ getyx(dialog, cur_y, cur_x);
+
+ nscroll = max_choice > scrlx ? -scrlx : -max_choice;
+ scrollok(menu, TRUE);
+ wscrl(menu, nscroll);
+ scrollok(menu, FALSE);
+
+ i = scrlx + nscroll;
+ PaintCheckItem(menu, items[i], 0, TRUE, checks[i]);
+ for (++i; i <= scrlx; i++)
+ PaintCheckItem(menu, items[i], i - (scrlx + nscroll), FALSE, checks[i]);
+ scrlx += nscroll;
+ PaintScroller(menu, scrlx + choice, item_no, menu_height);
+ wnoutrefresh(menu);
+ wrefresh(dialog);
+ continue;
+ }
+ }
+ i = 0;
+ }
+ else if (menu_height > 1 && key == KEY_NPAGE) {
+ if (choice == max_choice - 1) {
+ if (scrlx < max_scroll) {
+ /* Scroll menu up */
+ getyx(dialog, cur_y, cur_x);
+
+ nscroll = (scrlx + max_choice > max_scroll ?
+ max_scroll : scrlx + max_choice) - scrlx;
+ scrollok(menu, TRUE);
+ wscrl(menu, nscroll);
+ scrollok(menu, FALSE);
+
+ scrlx += nscroll;
+ for (i = 0; i < max_choice - 1; i++)
+ PaintCheckItem(menu, items[i + scrlx], i, FALSE, checks[i + scrlx]);
+ PaintCheckItem(menu, items[i + scrlx], max_choice - 1, TRUE, checks[i + scrlx]);
+ PaintScroller(menu, scrlx + choice, item_no, menu_height);
+ wnoutrefresh(menu);
+ wrefresh(dialog);
+ continue;
+ }
+ }
+ i = max_choice - 1;
+ }
+ else if (key == KEY_UP) {
+ if (!choice) {
+ if (scrlx) {
+ /* Scroll menu down */
+ getyx(dialog, cur_y, cur_x);
+ if (menu_height > 1) {
+ PaintCheckItem(menu, items[scrlx], 0, FALSE, checks[scrlx]);
+ scrollok(menu, TRUE);
+ wscrl(menu, - 1);
+ scrollok(menu, FALSE);
+ }
+ scrlx--;
+ PaintCheckItem(menu, items[scrlx], 0, TRUE, checks[scrlx]);
+ PaintScroller(menu, scrlx + choice, item_no, menu_height);
+ wnoutrefresh(menu);
+ wrefresh(dialog);
+ continue;
+ }
+ }
+ else
+ i = choice - 1;
+ }
+ else if (key == KEY_DOWN) {
+ if (choice == max_choice - 1) {
+ if (scrlx + choice < item_no - 1) {
+ /* Scroll menu up */
+ getyx(dialog, cur_y, cur_x);
+ if (menu_height > 1) {
+ PaintCheckItem(menu, items[scrlx + max_choice - 1], max_choice - 1, FALSE, checks[scrlx + max_choice - 1]);
+ scrollok(menu, TRUE);
+ scroll(menu);
+ scrollok(menu, FALSE);
+ }
+ scrlx++;
+ PaintCheckItem(menu, items[scrlx + max_choice - 1], max_choice - 1, TRUE, checks[scrlx + max_choice - 1]);
+ PaintScroller(menu, scrlx + choice, item_no, menu_height);
+ wnoutrefresh(menu);
+ wrefresh(dialog);
+ continue;
+ }
+ }
+ else
+ i = MIN(choice + 1, item_no - 1);
+ }
+
+ if (i != choice) {
+ getyx(dialog, cur_y, cur_x);
+ PaintCheckItem(menu, items[scrlx + choice], choice, FALSE, checks[scrlx + choice]);
+
+ choice = i;
+ PaintCheckItem(menu, items[scrlx + choice], choice, TRUE, checks[scrlx + choice]);
+ PaintScroller(menu, scrlx + choice, item_no, menu_height);
+ wnoutrefresh(menu);
+ wmove(dialog, cur_y, cur_x);
+ wrefresh(dialog);
+ continue;
+ }
+
+ switch (key) {
+ case TAB:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ if (!button) {
+ button = 1;
+ PaintButton(dialog, label1, y, x1, FALSE);
+ PaintButton(dialog, label2, y, x2, TRUE);
+ }
+ else {
+ button = 0;
+ PaintButton(dialog, label2, y, x2, FALSE);
+ PaintButton(dialog, label1, y, x1, TRUE);
+ }
+ wrefresh(dialog);
+ break;
+ case ' ':
+ getyx(dialog, cur_y, cur_x);
+ checks[scrlx + choice] = !checks[scrlx + choice];
+ PaintCheckItem(menu, items[scrlx + choice], choice, TRUE, checks[scrlx + choice]);
+ wmove(dialog, cur_y, cur_x);
+ wnoutrefresh(menu);
+ wrefresh(dialog);
+ break;
+ case '\r':
+ case '\n':
+ delwin(dialog);
+ return (!button ? 0 : -1);
+ default:
+ for (i = scrlx + choice + 1; i < item_no; i++)
+ if (toupper(items[i][0]) == toupper(key))
+ break;
+ if (i == item_no) {
+ for (i = 0; i < scrlx + choice; i++)
+ if (toupper(items[i][0]) == toupper(key))
+ break;
+ }
+ getyx(dialog, cur_y, cur_x);
+ if (i < item_no && i != scrlx + choice) {
+ if (i >= scrlx && i < scrlx + max_choice) {
+ /* it is already visible */
+ PaintCheckItem(menu, items[scrlx + choice], choice, FALSE, checks[scrlx + choice]);
+ choice = i - scrlx;
+ }
+ else {
+ scrlx = MIN(i, max_scroll);
+ choice = i - scrlx;
+ for (i = 0; i < max_choice; i++)
+ if (i != choice)
+ PaintCheckItem(menu, items[scrlx + i], i, FALSE, checks[scrlx + i]);
+ }
+ PaintCheckItem(menu, items[scrlx + choice], choice, TRUE, checks[scrlx + choice]);
+ PaintScroller(menu, scrlx + choice, item_no, menu_height);
+ wnoutrefresh(menu);
+ wmove(dialog, cur_y, cur_x);
+ wrefresh(dialog);
+ }
+ break;
+ }
+ }
+ /*NOTREACHED*/
+}
+
+static void
+PaintCheckItem(WINDOW *win, char *item, int choice, int selected, int checked)
+{
+ int i;
+
+ wattrset(win, selected ? title_attr : dialog_attr);
+ wmove(win, choice, 1);
+ for (i = 1; i < menu_width; i++)
+ waddch(win, ' ');
+ wmove(win, choice, item_x);
+ wattrset(win, selected ? title_attr : dialog_attr);
+ wprintw(win, "[%c] ", checked ? 'X' : ' ');
+ waddstr(win, item);
+}
+
+static char *
+DialogInput(char *title, char *prompt, int height, int width, char *init,
+ char *label1, char *label2, int def_button)
+{
+ int i, x, y, box_y, box_x, box_width, len,
+ input_x = 0, scrlx = 0, key = 0, button = -1, x1, x2, l1len, l2len;
+ char instr[1024 + 1];
+ WINDOW *dialog;
+
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+ dialog = newwin(height, width, y, x);
+ keypad(dialog, TRUE);
+
+ PaintWindow(dialog, title, 0, 0, height, width);
+
+ wattrset(dialog, dialog_attr);
+ PrintWrap(dialog, prompt, width - 3, 2, 3);
+
+ l1len = strlen(label1);
+ l2len = strlen(label2);
+
+ x1 = (width - (l1len + l2len)) / 3;
+ x2 = x1 + x1 + l1len;
+
+ box_width = width - 6;
+ getyx(dialog, y, x);
+ box_y = y + 2;
+ box_x = (width - box_width) / 2;
+ PaintBox(dialog, y + 1, box_x - 1, 3, box_width + 2);
+
+ x = width / 2 - 11;
+ y = height - 3;
+ PaintButton(dialog, label2, y, x2, def_button == 1);
+ PaintButton(dialog, label1, y, x1, def_button == 0);
+
+ memset(instr, '\0', sizeof(instr));
+ wmove(dialog, box_y, box_x);
+ wattrset(dialog, dialog_attr);
+ if (init)
+ strncpy(instr, init, sizeof(instr) - 2);
+
+ input_x = len = strlen(instr);
+ if (input_x >= box_width) {
+ scrlx = input_x - box_width + 1;
+ input_x = box_width - 1;
+ for (i = 0; i < box_width - 1; i++)
+ waddch(dialog, instr[scrlx + i]);
+ }
+ else
+ waddstr(dialog, instr);
+
+ wmove(dialog, box_y, box_x + input_x);
+
+ wrefresh(dialog);
+
+ while (1) {
+ key = wgetch(dialog);
+ if (button == -1) { /* Input box selected */
+ switch (key) {
+ case TAB:
+ case KEY_UP:
+ case KEY_DOWN:
+ break;
+ case KEY_LEFT:
+ if (scrlx && !input_x) {
+ --scrlx;
+ wmove(dialog, box_y, box_x);
+ for (i = 0; i < box_width; i++)
+ waddch(dialog, instr[scrlx + input_x + i] ? instr[scrlx + input_x + i] : ' ');
+ wmove(dialog, box_y, input_x + box_x);
+ wrefresh(dialog);
+ }
+ else if (input_x) {
+ wmove(dialog, box_y, --input_x + box_x);
+ wrefresh(dialog);
+ }
+ continue;
+ case KEY_RIGHT:
+ if (input_x + scrlx < len) {
+ if (input_x == box_width - 1) {
+ ++scrlx;
+ wmove(dialog, box_y, box_x);
+ for (i = scrlx; i < scrlx + box_width; i++)
+ waddch(dialog, instr[i] ? instr[i] : ' ');
+ wmove(dialog, box_y, input_x + box_x);
+ wrefresh(dialog);
+ }
+ else {
+ wmove(dialog, box_y, ++input_x + box_x);
+ wrefresh(dialog);
+ }
+ }
+ continue;
+ case KEY_BACKSPACE:
+ case 0177:
+ if (input_x || scrlx) {
+ wattrset(dialog, dialog_attr);
+
+ if (scrlx + input_x < len)
+ memmove(instr + scrlx + input_x - 1,
+ instr + scrlx + input_x,
+ len - (scrlx + input_x));
+ instr[--len] = '\0';
+
+ if (!input_x) {
+ scrlx = scrlx < box_width - 1 ? 0 : scrlx - (box_width - 1);
+ wmove(dialog, box_y, box_x);
+ for (i = 0; i < box_width; i++)
+ waddch(dialog, instr[scrlx + input_x + i] ? instr[scrlx + input_x + i] : ' ');
+ input_x = len - scrlx;
+ }
+ else {
+ wmove(dialog, box_y, --input_x + box_x);
+ for (i = scrlx + input_x; i < len &&
+ i < scrlx + box_width; i++)
+ waddch(dialog, instr[i]);
+ if (i < scrlx + box_width)
+ waddch(dialog, ' ');
+ }
+ wmove(dialog, box_y, input_x + box_x);
+ wrefresh(dialog);
+ }
+ continue;
+ case KEY_HOME:
+ case CONTROL_A:
+ wmove(dialog, box_y, box_x);
+ if (scrlx != 0) {
+ scrlx = 0;
+ for (i = 0; i < box_width; i++)
+ waddch(dialog, instr[i] ? instr[i] : ' ');
+ }
+ input_x = 0;
+ wmove(dialog, box_y, box_x);
+ wrefresh(dialog);
+ break;
+ case CONTROL_D:
+ if (input_x + scrlx < len) {
+ memmove(instr + scrlx + input_x,
+ instr + scrlx + input_x + 1,
+ len - (scrlx + input_x));
+ instr[--len] = '\0';
+ for (i = scrlx + input_x; i < len &&
+ i < scrlx + box_width; i++)
+ waddch(dialog, instr[i]);
+ if (i < scrlx + box_width)
+ waddch(dialog, ' ');
+ wmove(dialog, box_y, input_x + box_x);
+ wrefresh(dialog);
+ }
+ break;
+ case CONTROL_E:
+ case KEY_END:
+ if (box_width + scrlx < len) {
+ input_x = box_width - 1;
+ scrlx = len - box_width + 1;
+ wmove(dialog, box_y, box_x);
+ for (i = scrlx; i < scrlx + box_width; i++)
+ waddch(dialog, instr[i] ? instr[i] : ' ');
+ wmove(dialog, box_y, input_x + box_x);
+ wrefresh(dialog);
+ }
+ else {
+ input_x = len - scrlx;
+ wmove(dialog, box_y, input_x + box_x);
+ wrefresh(dialog);
+ }
+ break;
+ case CONTROL_K:
+ if (len) {
+ for (i = input_x; i < box_width; i++)
+ waddch(dialog, ' ');
+ for (i = scrlx + input_x; i < len; i++)
+ instr[i] = '\0';
+ len = scrlx + input_x;
+ wmove(dialog, box_y, box_x + input_x);
+ wrefresh(dialog);
+ }
+ break;
+ default:
+ if (key < 0x100 && isprint(key)) {
+ if (scrlx + input_x < sizeof(instr) - 1) {
+ wattrset(dialog, dialog_attr);
+ if (scrlx + input_x < len) {
+ memmove(instr + scrlx + input_x + 1,
+ instr + scrlx + input_x,
+ len - (scrlx + input_x));
+ }
+ instr[scrlx + input_x] = key;
+ instr[++len] = '\0';
+ if (input_x == box_width - 1) {
+ scrlx++;
+ wmove(dialog, box_y, box_x);
+ for (i = 0; i < box_width - 1; i++)
+ waddch(dialog, instr[scrlx + i]);
+ }
+ else {
+ wmove(dialog, box_y, input_x++ + box_x);
+ for (i = scrlx + input_x - 1; i < len &&
+ i < scrlx + box_width; i++)
+ waddch(dialog, instr[i]);
+ wmove(dialog, box_y, input_x + box_x);
+ }
+ wrefresh(dialog);
+ }
+ else
+ flash(); /* Alarm user about overflow */
+ continue;
+ }
+ }
+ }
+
+ switch (key) {
+ case KEY_UP:
+ case KEY_LEFT:
+ switch (button) {
+ case -1:
+ button = 1; /* Indicates "Cancel" button is selected */
+ PaintButton(dialog, label1, y, x1, FALSE);
+ PaintButton(dialog, label2, y, x2, TRUE);
+ wrefresh(dialog);
+ break;
+ case 0:
+ button = -1; /* Indicates input box is selected */
+ PaintButton(dialog, label2, y, x2, FALSE);
+ PaintButton(dialog, label1, y, x1, TRUE);
+ wmove(dialog, box_y, box_x + input_x);
+ wrefresh(dialog);
+ break;
+ case 1:
+ button = 0; /* Indicates "OK" button is selected */
+ PaintButton(dialog, label2, y, x2, FALSE);
+ PaintButton(dialog, label1, y, x1, TRUE);
+ wrefresh(dialog);
+ break;
+ }
+ break;
+ case TAB:
+ case KEY_DOWN:
+ case KEY_RIGHT:
+ switch (button) {
+ case -1:
+ button = 0; /* Indicates "OK" button is selected */
+ PaintButton(dialog, label2, y, x2, FALSE);
+ PaintButton(dialog, label1, y, x1, TRUE);
+ wrefresh(dialog);
+ break;
+ case 0:
+ button = 1; /* Indicates "Cancel" button is selected */
+ PaintButton(dialog, label1, y, x1, FALSE);
+ PaintButton(dialog, label2, y, x2, TRUE);
+ wrefresh(dialog);
+ break;
+ case 1:
+ button = -1; /* Indicates input box is selected */
+ PaintButton(dialog, label2, y, x2, FALSE);
+ PaintButton(dialog, label1, y, x1, TRUE);
+ wmove(dialog, box_y, box_x + input_x);
+ wrefresh(dialog);
+ break;
+ }
+ break;
+ case ' ':
+ case '\r':
+ case '\n':
+ delwin(dialog);
+ return (button != 1 ? XtNewString(instr) : NULL);
+ }
+ }
+}
diff --git a/hw/xfree86/utils/xorgcfg/up.xbm b/hw/xfree86/utils/xorgcfg/up.xbm
new file mode 100644
index 000000000..64f8f9ec4
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/up.xbm
@@ -0,0 +1,8 @@
+#define up_width 19
+#define up_height 19
+static unsigned char up_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x07, 0x00, 0x80, 0x0f, 0x00, 0xc0, 0x1f, 0x00, 0xe0, 0x3f, 0x00,
+ 0xf0, 0x7f, 0x00, 0xf8, 0xff, 0x00, 0xfc, 0xff, 0x01, 0x80, 0x0f, 0x00,
+ 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x80, 0x0f, 0x00,
+ 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/hw/xfree86/utils/xorgcfg/vidmode.c b/hw/xfree86/utils/xorgcfg/vidmode.c
new file mode 100644
index 000000000..d28ac0899
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/vidmode.c
@@ -0,0 +1,1357 @@
+/*
+ * 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/vidmode.c,v 1.7 2001/07/07 23:00:43 paulo Exp $
+ */
+
+/*
+ * Most of the code here is based on the xvidtune code.
+ */
+
+#include "vidmode.h"
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/MenuButton.h>
+#include <X11/Xaw/Repeater.h>
+#include <X11/Shell.h>
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/Dialog.h>
+#include <X11/Xaw/SimpleMenP.h>
+#include <X11/Xaw/SmeBSB.h>
+#include <X11/Xaw/Toggle.h>
+#include "xf86config.h"
+
+#define V_FLAG_MASK 0x1FF
+#define V_PHSYNC 0x001
+#define V_NHSYNC 0x002
+#define V_PVSYNC 0x004
+#define V_NVSYNC 0x008
+#define V_INTERLACE 0x010
+#define V_DBLSCAN 0x020
+#define V_CSYNC 0x040
+#define V_PCSYNC 0x080
+#define V_NCSYNC 0x100
+
+#define LEFT 0
+#define RIGHT 1
+#define UP 2
+#define DOWN 3
+#define WIDER 4
+#define TALLER 5
+#define NARROWER 6
+#define SHORTER 7
+
+#define HDISPLAY 0
+#define VDISPLAY 1
+#define HSYNCSTART 2
+#define HSYNCEND 3
+#define HTOTAL 4
+#define VSYNCSTART 5
+#define VSYNCEND 6
+#define VTOTAL 7
+#define FLAGS 8
+#define CLOCK 9
+#define HSYNC 10
+#define VSYNC 11
+
+#define MINMAJOR 2
+#define MINMINOR 0
+
+/*
+ * Types
+ */
+typedef struct {
+ char *ident;
+ XF86VidModeModeInfo info;
+} xf86cfgVesaModeInfo;
+
+/*
+ * Prototypes
+ */
+static Bool GetModeLine(Bool);
+static void StartAdjustMonitorCallback(Widget, XtPointer, XtPointer);
+static void AdjustMonitorCallback(Widget, XtPointer, XtPointer);
+static void EndAdjustMonitorCallback(Widget, XtPointer, XtPointer);
+static void SetLabel(int, int);
+static void UpdateSyncRates(Bool);
+static int VidmodeError(Display*, XErrorEvent*);
+static void CleanUp(Display*);
+static void ApplyCallback(Widget, XtPointer, XtPointer);
+static void AutoCallback(Widget, XtPointer, XtPointer);
+static void RestoreCallback(Widget, XtPointer, XtPointer);
+static void SelectCallback(Widget, XtPointer, XtPointer);
+static void SelectMonitorCallback(Widget, XtPointer, XtPointer);
+static void SwitchCallback(Widget, XtPointer, XtPointer);
+static void SetLabels(void);
+static void UpdateCallback(Widget, XtPointer, XtPointer);
+static void ChangeScreenCallback(Widget, XtPointer, XtPointer);
+static void SetLabelAndModeline(void);
+static void AddVesaModeCallback(Widget, XtPointer, XtPointer);
+static void GetModes(void);
+static void AddModeCallback(Widget, XtPointer, XtPointer);
+static void TestCallback(Widget, XtPointer, XtPointer);
+static void TestTimeout(XtPointer, XtIntervalId*);
+static void StopTestCallback(Widget, XtPointer, XtPointer);
+static int ForceAddMode(void);
+static int AddMode(void);
+/*
+ * Initialization
+ */
+extern Widget work;
+Widget vtune;
+static Widget apply, automatic, restore, mode, menu, screenb, screenp;
+static Bool autoflag;
+static xf86cfgVidmode *vidtune;
+static XF86VidModeModeLine modeline, orig_modeline;
+static int dot_clock, hsync_rate, vsync_rate, hitError;
+static Bool S3Specials;
+static int invert_vclk, blank1, blank2, early_sc, screenno;
+static int (*XtErrorFunc)(Display*, XErrorEvent*);
+static Widget labels[VSYNC + 1], values[VSYNC + 1], repeater, monitor,
+ monitorb, add, text, vesab, vesap, forceshell, testshell, addshell;
+static int MajorVersion, MinorVersion, EventBase, ErrorBase;
+static XtIntervalId timeout;
+
+/* The information bellow is extracted from
+ * xc/programs/Xserver/hw/xfree86/etc/vesamodes
+ * If that file is changed, please update the table bellow also. Or even
+ * better, write a script to generate the table.
+ */
+static xf86cfgVesaModeInfo vesamodes[] = {
+ {
+ "640x350 @ 85Hz (VESA) hsync: 37.9kHz",
+ {
+ 31500, 640, 672, 736, 832, 0, 350, 382, 385, 445,
+ V_PHSYNC | V_NVSYNC
+ }
+ },
+ {
+ "640x400 @ 85Hz (VESA) hsync: 37.9kHz",
+ {
+ 31500, 640, 672, 736, 832, 0, 400, 401, 404, 445,
+ V_NHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "720x400 @ 85Hz (VESA) hsync: 37.9kHz",
+ {
+ 35500, 720, 756, 828, 936, 0, 400, 401, 404, 446,
+ V_NHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "640x480 @ 60Hz (Industry standard) hsync: 31.5kHz",
+ {
+ 25200, 640, 656, 752, 800, 0, 480, 490, 492, 525,
+ V_NHSYNC | V_NVSYNC
+ }
+ },
+ {
+ "640x480 @ 72Hz (VESA) hsync: 37.9kHz",
+ {
+ 31500, 640, 664, 704, 832, 0, 480, 489, 491, 520,
+ V_NHSYNC | V_NVSYNC
+ }
+ },
+ {
+ "640x480 @ 75Hz (VESA) hsync: 37.5kHz",
+ {
+ 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500,
+ V_NHSYNC | V_NVSYNC
+ }
+ },
+ {
+ "640x480 @ 85Hz (VESA) hsync: 43.3kHz",
+ {
+ 36000, 640, 696, 752, 832, 0, 480, 481, 484, 509,
+ V_NHSYNC | V_NVSYNC
+ }
+ },
+ {
+ "800x600 @ 56Hz (VESA) hsync: 35.2kHz",
+ {
+ 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "800x600 @ 60Hz (VESA) hsync: 37.9kHz",
+ {
+ 400000, 800, 840, 968, 1056, 0, 600, 601, 605, 628,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "800x600 @ 72Hz (VESA) hsync: 48.1kHz",
+ {
+ 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "800x600 @ 75Hz (VESA) hsync: 46.9kHz",
+ {
+ 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "800x600 @ 85Hz (VESA) hsync: 53.7kHz",
+ {
+ 563000, 800, 832, 896, 1048, 0, 600, 601, 604, 631,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1024x768i @ 43Hz (industry standard) hsync: 35.5kHz",
+ {
+ 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 776, 817,
+ V_PHSYNC | V_PVSYNC | V_INTERLACE
+ }
+ },
+ {
+ "1024x768 @ 60Hz (VESA) hsync: 48.4kHz",
+ {
+ 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806,
+ V_NHSYNC | V_NVSYNC
+ }
+ },
+ {
+ "1024x768 @ 70Hz (VESA) hsync: 56.5kHz",
+ {
+ 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806,
+ V_NHSYNC | V_NVSYNC
+ }
+ },
+ {
+ "1024x768 @ 75Hz (VESA) hsync: 60.0kHz",
+ {
+ 78800, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1024x768 @ 85Hz (VESA) hsync: 68.7kHz",
+ {
+ 94500, 1024, 1072, 1168, 1376, 0, 768, 769, 772, 808,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1152x864 @ 75Hz (VESA) hsync: 67.5kHz",
+ {
+ 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1280x960 @ 60Hz (VESA) hsync: 60.0kHz",
+ {
+ 108000, 1280, 1376, 1488, 1800, 0, 960, 961, 964, 1000,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1280x960 @ 85Hz (VESA) hsync: 85.9kHz",
+ {
+ 148500, 1280, 1344, 1504, 1728, 0, 960, 961, 964, 1011,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1280x1024 @ 60Hz (VESA) hsync: 64.0kHz",
+ {
+ 108000, 1280, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1280x1024 @ 75Hz (VESA) hsync: 80.0kHz",
+ {
+ 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1280x1024 @ 85Hz (VESA) hsync: 91.1kHz",
+ {
+ 157500, 1280, 1344, 1504, 1728, 0, 1024, 1025, 1028, 1072,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1600x1200 @ 60Hz (VESA) hsync: 75.0kHz",
+ {
+ 162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1600x1200 @ 65Hz (VESA) hsync: 81.3kHz",
+ {
+ 175500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1600x1200 @ 70Hz (VESA) hsync: 87.5kHz",
+ {
+ 189000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1600x1200 @ 75Hz (VESA) hsync: 93.8kHz",
+ {
+ 202500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1600x1200 @ 85Hz (VESA) hsync: 106.3kHz",
+ {
+ 229500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
+ V_PHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1792x1344 @ 60Hz (VESA) hsync: 83.6kHz",
+ {
+ 204800, 1792, 1920, 2120, 2448, 0, 1344, 1345, 1348, 1394,
+ V_NHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1792x1344 @ 75Hz (VESA) hsync: 106.3kHz",
+ {
+ 261000, 1792, 1888, 2104, 2456, 0, 1344, 1345, 1348, 1417,
+ V_NHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1856x1392 @ 60Hz (VESA) hsync: 86.3kHz",
+ {
+ 218300, 1856, 1952, 2176, 2528, 0, 1392, 1393, 1396, 1439,
+ V_NHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1856x1392 @ 75Hz (VESA) hsync: 112.5kHz",
+ {
+ 288000, 1856, 1984, 2208, 2560, 0, 1392, 1393, 1396, 1500,
+ V_NHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1920x1440 @ 60Hz (VESA) hsync: 90.0kHz",
+ {
+ 234000, 1920, 2048, 2256, 2600, 0, 1440, 1441, 1444, 1500,
+ V_NHSYNC | V_PVSYNC
+ }
+ },
+ {
+ "1920x1440 @ 75Hz (VESA) hsync: 112.5kHz",
+ {
+ 297000, 1920, 2064, 2288, 2640, 0, 1440, 1441, 1444, 1500,
+ V_NHSYNC | V_PVSYNC
+ }
+ },
+};
+
+/*
+ * Implementation
+ */
+Bool
+VideoModeInitialize(void)
+{
+ Widget form;
+ char dispstr[128], *ptr, *tmp;
+
+ static char *names[] = {
+ NULL,
+ NULL,
+ "hsyncstart",
+ "hsyncend",
+ "htotal",
+ "vsyncstart",
+ "vsyncend",
+ "vtotal",
+ "flags",
+ "clock",
+ "hsync",
+ "vsync",
+ };
+ static char *vnames[] = {
+ NULL,
+ NULL,
+ "v-hsyncstart",
+ "v-hsyncend",
+ "v-htotal",
+ "v-vsyncstart",
+ "v-vsyncend",
+ "v-vtotal",
+ "v-flags",
+ "v-clock",
+ "v-hsync",
+ "v-vsync",
+ };
+ Widget rep;
+ int i;
+
+ if (!XF86VidModeQueryVersion(XtDisplay(toplevel),
+ &MajorVersion, &MinorVersion)) {
+ fprintf(stderr, "Unable to query video extension version\n");
+ return (False);
+ }
+ else if (!XF86VidModeQueryExtension(XtDisplay(toplevel),
+ &EventBase, &ErrorBase)) {
+ fprintf(stderr, "Unable to query video extension information\n");
+ return (False);
+ }
+ else if (MajorVersion < MINMAJOR ||
+ (MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) {
+ fprintf(stderr,
+ "Xserver is running an old XFree86-VidModeExtension version"
+ " (%d.%d)\n", MajorVersion, MinorVersion);
+ fprintf(stderr, "Minimum required version is %d.%d\n",
+ MINMAJOR, MINMINOR);
+ return (False);
+ }
+ else
+ InitializeVidmodes();
+
+ vtune = XtCreateWidget("vidtune", formWidgetClass,
+ work, NULL, 0);
+
+ vesab = XtVaCreateManagedWidget("vesaB", menuButtonWidgetClass, vtune,
+ XtNmenuName, "vesaP", NULL, 0);
+ vesap = XtCreatePopupShell("vesaP", simpleMenuWidgetClass, vtune, NULL, 0);
+ for (i = 0; i < sizeof(vesamodes) / sizeof(vesamodes[0]); i++) {
+ rep = XtCreateManagedWidget(vesamodes[i].ident, smeBSBObjectClass,
+ vesap, NULL, 0);
+ XtAddCallback(rep, XtNcallback, AddVesaModeCallback,
+ (XtPointer)&vesamodes[i]);
+ }
+
+ rep = XtCreateManagedWidget("prev", commandWidgetClass, vtune, NULL, 0);
+ XtAddCallback(rep, XtNcallback, SwitchCallback, (XtPointer)-1);
+ mode = XtCreateManagedWidget("mode", menuButtonWidgetClass, vtune, NULL, 0);
+ rep = XtCreateManagedWidget("next", commandWidgetClass, vtune, NULL, 0);
+ XtAddCallback(rep, XtNcallback, SwitchCallback, (XtPointer)1);
+
+ screenp = XtCreatePopupShell("screenP", simpleMenuWidgetClass, vtune,
+ NULL, 0);
+
+ XmuSnprintf(dispstr, sizeof(dispstr), "%s",
+ DisplayString(XtDisplay(toplevel)));
+ ptr = strrchr(dispstr, '.');
+ tmp = strrchr(dispstr, ':');
+ if (tmp != NULL && ptr != NULL && ptr > tmp)
+ *ptr = '\0';
+
+ for (i = 0; i < ScreenCount(XtDisplay(toplevel)); i++) {
+ char name[128];
+
+ XmuSnprintf(name, sizeof(name), "%s.%d", dispstr, i);
+ rep = XtCreateManagedWidget(name, smeBSBObjectClass, screenp,
+ NULL, 0);
+ XtAddCallback(rep, XtNcallback, ChangeScreenCallback,
+ (XtPointer)(long)i);
+ if (i == 0) {
+ screenb = XtVaCreateManagedWidget("screenB", menuButtonWidgetClass,
+ vtune,
+ XtNmenuName, "screenP",
+ XtNlabel, name,
+ NULL, 0);
+ }
+ }
+ XtRealizeWidget(screenp);
+
+ rep = XtCreateManagedWidget("up", repeaterWidgetClass,
+ vtune, NULL, 0);
+ XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
+ XtAddCallback(rep, XtNcallback,
+ AdjustMonitorCallback, (XtPointer)UP);
+ XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
+ rep = XtCreateManagedWidget("left", repeaterWidgetClass,
+ vtune, NULL, 0);
+ XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
+ XtAddCallback(rep, XtNcallback,
+ AdjustMonitorCallback, (XtPointer)LEFT);
+ XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
+ XtCreateManagedWidget("monitor", simpleWidgetClass, vtune, NULL, 0);
+ rep = XtCreateManagedWidget("right", repeaterWidgetClass,
+ vtune, NULL, 0);
+ XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
+ XtAddCallback(rep, XtNcallback,
+ AdjustMonitorCallback, (XtPointer)RIGHT);
+ XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
+ rep = XtCreateManagedWidget("down", repeaterWidgetClass,
+ vtune, NULL, 0);
+ XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
+ XtAddCallback(rep, XtNcallback,
+ AdjustMonitorCallback, (XtPointer)DOWN);
+ XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
+ rep = XtCreateManagedWidget("wider", repeaterWidgetClass,
+ vtune, NULL, 0);
+ XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
+ XtAddCallback(rep, XtNcallback,
+ AdjustMonitorCallback, (XtPointer)WIDER);
+ XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
+ rep = XtCreateManagedWidget("narrower", repeaterWidgetClass,
+ vtune, NULL, 0);
+ XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
+ XtAddCallback(rep, XtNcallback,
+ AdjustMonitorCallback, (XtPointer)NARROWER);
+ XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
+ rep = XtCreateManagedWidget("shorter", repeaterWidgetClass,
+ vtune, NULL, 0);
+ XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
+ XtAddCallback(rep, XtNcallback,
+ AdjustMonitorCallback, (XtPointer)SHORTER);
+ XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
+ rep = XtCreateManagedWidget("taller", repeaterWidgetClass,
+ vtune, NULL, 0);
+ XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
+ XtAddCallback(rep, XtNcallback,
+ AdjustMonitorCallback, (XtPointer)TALLER);
+ XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
+
+ automatic = XtCreateManagedWidget("auto", toggleWidgetClass, vtune, NULL, 0);
+ XtAddCallback(automatic, XtNcallback, AutoCallback, NULL);
+ apply = XtCreateManagedWidget("apply", commandWidgetClass, vtune, NULL, 0);
+ XtAddCallback(apply, XtNcallback, ApplyCallback, NULL);
+ restore = XtCreateManagedWidget("restore", commandWidgetClass, vtune, NULL, 0);
+ XtAddCallback(restore, XtNcallback, RestoreCallback, NULL);
+ rep = XtCreateManagedWidget("update", commandWidgetClass, vtune, NULL, 0);
+ XtAddCallback(rep, XtNcallback, UpdateCallback, NULL);
+ rep = XtCreateManagedWidget("test", commandWidgetClass, vtune, NULL, 0);
+ XtAddCallback(rep, XtNcallback, TestCallback, NULL);
+
+ form = XtCreateManagedWidget("form", formWidgetClass, vtune, NULL, 0);
+ for (i = 2; i < VSYNC + 1; i++) {
+ labels[i] = XtCreateManagedWidget(names[i], labelWidgetClass,
+ form, NULL, 0);
+ values[i] = XtCreateManagedWidget(vnames[i], labelWidgetClass,
+ form, NULL, 0);
+ }
+
+ add = XtCreateManagedWidget("add", commandWidgetClass, vtune, NULL, 0);
+ XtAddCallback(add, XtNcallback, AddModeCallback, NULL);
+ XtCreateManagedWidget("addto", labelWidgetClass, vtune, NULL, 0);
+ monitorb = XtCreateManagedWidget("ident", menuButtonWidgetClass, vtune,
+ NULL, 0);
+ XtCreateManagedWidget("as", labelWidgetClass, vtune, NULL, 0);
+ text = XtVaCreateManagedWidget("text", asciiTextWidgetClass, vtune,
+ XtNeditType, XawtextEdit, NULL, 0);
+
+ XtRealizeWidget(vtune);
+
+ return (True);
+}
+
+void
+InitializeVidmodes(void)
+{
+ int i;
+ Display *display = XtDisplay(toplevel);
+
+ computer.num_vidmodes = ScreenCount(display);
+ computer.vidmodes = (xf86cfgVidmode**)
+ XtMalloc(sizeof(xf86cfgVidmode*) * computer.num_vidmodes);
+ for (i = 0; i < computer.num_vidmodes; i++) {
+
+ computer.vidmodes[i] = (xf86cfgVidmode*)
+ XtCalloc(1, sizeof(xf86cfgVidmode));
+ computer.vidmodes[i]->screen = i;
+ }
+}
+
+void
+VideoModeConfigureStart(void)
+{
+ vidtune = computer.vidmodes[screenno];
+
+ XtSetSensitive(vtune, vidtune != NULL);
+ if (!XtIsManaged(vtune))
+ XtManageChild(vtune);
+ else
+ XtMapWidget(vtune);
+ if (vidtune != NULL) {
+ Arg args[1];
+ Boolean state;
+ XF86ConfMonitorPtr mon;
+ static char menuName[16];
+ static int menuN;
+
+ XtErrorFunc = XSetErrorHandler(VidmodeError);
+ XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, True);
+ GetModeLine(True);
+ GetModes();
+
+ SetLabels();
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(automatic, args, 1);
+ XtSetSensitive(apply, !state);
+ autoflag = state;
+
+ if (monitor)
+ XtDestroyWidget(monitor);
+ XmuSnprintf(menuName, sizeof(menuName), "menuP%d", menuN);
+ menuN = !menuN;
+ monitor = XtCreatePopupShell(menuName, simpleMenuWidgetClass,
+ vtune, NULL, 0);
+ XtVaSetValues(monitorb, XtNmenuName, menuName, NULL, 0);
+
+ mon = XF86Config->conf_monitor_lst;
+ while (mon != NULL) {
+ Widget sme = XtCreateManagedWidget(mon->mon_identifier,
+ smeBSBObjectClass,
+ monitor, NULL, 0);
+ XtAddCallback(sme, XtNcallback,
+ SelectMonitorCallback, (XtPointer)mon);
+
+ /* guess the monitor at a given screen and/or
+ * updates configuration if a monitor was removed from the
+ * configuration.
+ */
+ if (XF86Config->conf_layout_lst) {
+ XF86ConfAdjacencyPtr adj = XF86Config->conf_layout_lst->
+ lay_adjacency_lst;
+
+ while (adj != NULL) {
+ if (adj->adj_screen != NULL) {
+ if (adj->adj_screen->scrn_monitor == mon &&
+ adj->adj_scrnum >= 0 &&
+ adj->adj_scrnum < ScreenCount(XtDisplay(toplevel))) {
+ if (computer.vidmodes[adj->adj_scrnum]->monitor ==
+ NULL || computer.vidmodes[adj->adj_scrnum]->
+ monitor == adj->adj_screen->scrn_monitor) {
+ computer.vidmodes[adj->adj_scrnum]->monitor =
+ adj->adj_screen->scrn_monitor;
+ break;
+ }
+ else
+ computer.vidmodes[adj->adj_scrnum]->monitor =
+ NULL;
+ }
+ }
+ adj = (XF86ConfAdjacencyPtr)(adj->list.next);
+ }
+ }
+ mon = (XF86ConfMonitorPtr)(mon->list.next);
+ }
+ SetLabelAndModeline();
+ }
+}
+
+void
+VideoModeConfigureEnd(void)
+{
+ XtUnmapWidget(vtune);
+ if (vidtune != NULL) {
+ XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, False);
+ XSetErrorHandler(XtErrorFunc);
+ }
+ vidtune = NULL;
+}
+
+static void
+SetLabelAndModeline(void)
+{
+ if (vidtune->monitor != NULL) {
+ char string[32];
+
+ XtVaSetValues(monitorb, XtNlabel,
+ vidtune->monitor->mon_identifier, NULL);
+ XtSetSensitive(add, True);
+
+ if (modeline.htotal && modeline.vtotal)
+ XmuSnprintf(string, sizeof(string), "%dx%d@%d",
+ modeline.hdisplay, modeline.vdisplay,
+ (int)((double)dot_clock / (double)modeline.htotal * 1000.0 /
+ (double)modeline.vtotal));
+ else
+ XmuSnprintf(string, sizeof(string), "%dx%d",
+ modeline.hdisplay, modeline.vdisplay);
+ XtVaSetValues(text, XtNstring, string, NULL);
+ }
+ else {
+ XtVaSetValues(monitorb, XtNlabel, "", NULL);
+ XtSetSensitive(add, False);
+ XtVaSetValues(text, XtNstring, "", NULL);
+ }
+}
+
+/*ARGSUSED*/
+void
+VidmodeRestoreAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ if (vidtune != NULL) {
+ if (timeout != 0)
+ StopTestCallback(w, NULL, NULL);
+ else
+ RestoreCallback(w, NULL, NULL);
+ }
+}
+
+static void
+UpdateSyncRates(Bool update)
+{
+ if (modeline.htotal && modeline.vtotal) {
+ hsync_rate = (dot_clock * 1000) / modeline.htotal;
+ vsync_rate = (hsync_rate * 1000) / modeline.vtotal;
+ if (modeline.flags & V_INTERLACE)
+ vsync_rate *= 2;
+ else if (modeline.flags & V_DBLSCAN)
+ vsync_rate /= 2;
+ if (update) {
+ SetLabel(HSYNC, hsync_rate);
+ SetLabel(VSYNC, vsync_rate);
+ }
+ }
+}
+
+static void
+SetLabel(int ident, int value)
+{
+ Arg args[1];
+ char label[256];
+
+ if (ident == FLAGS) {
+ int len = 0;
+
+ *label = '\0';
+ if (value & V_PHSYNC)
+ len += XmuSnprintf(label, sizeof(label), "%s", "+hsync");
+ if (modeline.flags & V_NHSYNC)
+ len += XmuSnprintf(label + len, sizeof(label), "%s%s",
+ len ? " " : "", "-hsync");
+ if (value & V_PVSYNC)
+ len += XmuSnprintf(label + len, sizeof(label), "%s%s",
+ len ? " " : "", "+vsync");
+ if (value & V_NVSYNC)
+ len += XmuSnprintf(label + len, sizeof(label), "%s%s",
+ len ? " " : "", "-vsync");
+ if (value & V_INTERLACE)
+ len += XmuSnprintf(label + len, sizeof(label), "%s%s",
+ len ? " " : "", "interlace");
+ if (value & V_CSYNC)
+ len += XmuSnprintf(label + len, sizeof(label), "%s%s",
+ len ? " " : "", "composite");
+ if (value & V_PCSYNC)
+ len += XmuSnprintf(label + len, sizeof(label), "%s%s",
+ len ? " " : "", "+csync");
+ if (value & V_NCSYNC)
+ len += XmuSnprintf(label + len, sizeof(label), "%s%s",
+ len ? " " : "", "-csync");
+ if (value & V_DBLSCAN)
+ len += XmuSnprintf(label + len, sizeof(label), "%s%s",
+ len ? " " : "", "doublescan");
+
+ }
+ else if (ident == CLOCK || ident == HSYNC || ident == VSYNC)
+ XmuSnprintf(label, sizeof(label), "%6.2f", (float)value / 1000.0);
+ else
+ XmuSnprintf(label, sizeof(label), "%d", value);
+
+ XtSetArg(args[0], XtNlabel, label);
+ XtSetValues(values[ident], args, 1);
+}
+
+/*ARGSUSED*/
+static void
+StartAdjustMonitorCallback(Widget w, XtPointer client_data, XtPointer call_data)
+{
+ repeater = w;
+}
+
+static void
+AdjustMonitorCallback(Widget w, XtPointer client_data, XtPointer call_data)
+{
+ if (repeater != w)
+ return;
+ switch ((long)client_data) {
+ case LEFT:
+ if (modeline.hsyncend + 4 < modeline.htotal) {
+ modeline.hsyncstart += 4;
+ modeline.hsyncend += 4;
+ SetLabel(HSYNCSTART, modeline.hsyncstart);
+ SetLabel(HSYNCEND, modeline.hsyncend);
+ }
+ else
+ XBell(XtDisplay(w), 80);
+ break;
+ case RIGHT:
+ if (modeline.hsyncstart - 4 > modeline.hdisplay) {
+ modeline.hsyncstart -= 4;
+ modeline.hsyncend -= 4;
+ SetLabel(HSYNCSTART, modeline.hsyncstart);
+ SetLabel(HSYNCEND, modeline.hsyncend);
+ }
+ else
+ XBell(XtDisplay(w), 80);
+ break;
+ case NARROWER:
+ modeline.htotal += 4;
+ SetLabel(HTOTAL, modeline.htotal);
+ UpdateSyncRates(True);
+ break;
+ case WIDER:
+ if (modeline.htotal - 4 > modeline.hsyncend) {
+ modeline.htotal -= 4;
+ SetLabel(HTOTAL, modeline.htotal);
+ UpdateSyncRates(True);
+ }
+ else
+ XBell(XtDisplay(w), 80);
+ break;
+ case UP:
+ if (modeline.vsyncend + 4 < modeline.vtotal) {
+ modeline.vsyncstart += 4;
+ modeline.vsyncend += 4;
+ SetLabel(VSYNCSTART, modeline.vsyncstart);
+ SetLabel(VSYNCEND, modeline.vsyncend);
+ }
+ else
+ XBell(XtDisplay(w), 80);
+ break;
+ case DOWN:
+ if (modeline.vsyncstart - 4 > modeline.vdisplay) {
+ modeline.vsyncstart -= 4;
+ modeline.vsyncend -= 4;
+ SetLabel(VSYNCSTART, modeline.vsyncstart);
+ SetLabel(VSYNCEND, modeline.vsyncend);
+ }
+ else
+ XBell(XtDisplay(w), 80);
+ break;
+ case SHORTER:
+ modeline.vtotal += 4;
+ SetLabel(VTOTAL, modeline.vtotal);
+ UpdateSyncRates(True);
+ break;
+ case TALLER:
+ if (modeline.vtotal - 4 > modeline.vsyncend) {
+ modeline.vtotal -= 4;
+ SetLabel(VTOTAL, modeline.vtotal);
+ UpdateSyncRates(True);
+ }
+ else
+ XBell(XtDisplay(w), 80);
+ break;
+ }
+
+ if (autoflag)
+ ApplyCallback(w, call_data, client_data);
+}
+
+/*ARGSUSED*/
+static void
+EndAdjustMonitorCallback(Widget w, XtPointer client_data, XtPointer call_data)
+{
+ repeater = NULL;
+}
+
+static Bool
+GetModeLine(Bool save)
+{
+ if (XF86VidModeGetModeLine(XtDisplay(toplevel), vidtune->screen,
+ &dot_clock, &modeline)) {
+ if (save)
+ memcpy(&orig_modeline, &modeline, sizeof(XF86VidModeModeLine));
+ UpdateSyncRates(False);
+ if (modeline.privsize != 0 && modeline.private != NULL) {
+ S3Specials = True;
+ invert_vclk = modeline.private[1];
+ blank1 = modeline.private[2] & 7;
+ blank2 = (modeline.private[2] >> 4) & 7;
+ early_sc = modeline.private[3];
+ }
+ else
+ S3Specials = False;
+ return (True);
+ }
+
+ return (False);
+}
+
+static void
+CleanUp(Display *display)
+{
+ /* Make sure mode switching is not locked out at exit */
+ XF86VidModeLockModeSwitch(display, vidtune->screen, False);
+ XFlush(display);
+}
+
+static int
+VidmodeError(Display *display, XErrorEvent *error)
+{
+ if ((error->error_code >= ErrorBase &&
+ error->error_code < ErrorBase + XF86VidModeNumberErrors) ||
+ error->error_code == BadValue) {
+ hitError = 1;
+ }
+ else {
+ CleanUp(display);
+ if (XtErrorFunc)
+ (*XtErrorFunc)(display, error);
+ }
+ return (0);
+}
+
+/*ARGSUSED*/
+static void
+ApplyCallback(Widget w, XtPointer call_data, XtPointer client_data)
+{
+ hitError = 0;
+ XF86VidModeModModeLine(XtDisplay(w), vidtune->screen, &modeline);
+ XSync(XtDisplay(w), False);
+ if (hitError) {
+ if (repeater != NULL) {
+ XtCallActionProc(repeater, "unset", NULL, NULL, 0);
+ XtCallActionProc(repeater, "stop", NULL, NULL, 0);
+ repeater = NULL;
+ }
+ XBell(XtDisplay(w), 80);
+ if (timeout)
+ StopTestCallback(w, NULL, NULL);
+ GetModeLine(False);
+ SetLabels();
+ }
+}
+
+/*ARGSUSED*/
+static void
+AutoCallback(Widget w, XtPointer call_data, XtPointer client_data)
+{
+ autoflag = (Bool)(long)client_data;
+ XtSetSensitive(apply, !autoflag);
+}
+
+static void
+RestoreCallback(Widget w, XtPointer call_data, XtPointer client_data)
+{
+ memcpy(&modeline, &orig_modeline, sizeof(XF86VidModeModeLine));
+ if (autoflag)
+ ApplyCallback(w, call_data, client_data);
+ SetLabels();
+}
+
+static void
+SelectCallback(Widget w, XtPointer call_data, XtPointer client_data)
+{
+ XF86VidModeModeInfo *info = (XF86VidModeModeInfo*)call_data;
+ Arg args[1];
+ Bool result;
+
+ XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, False);
+ result = XF86VidModeSwitchToMode(XtDisplay(toplevel), vidtune->screen, info);
+ XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, True);
+ if (!result)
+ return;
+
+ XtSetArg(args[0], XtNlabel, XtName(w));
+ XtSetValues(mode, args, 1);
+ UpdateCallback(w, call_data, client_data);
+}
+
+static void
+SwitchCallback(Widget w, XtPointer call_data, XtPointer client_data)
+{
+ int direction = (long)call_data;
+ Arg args[1];
+ Bool result;
+ char label[32];
+
+ XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, False);
+ result = XF86VidModeSwitchMode(XtDisplay(toplevel), vidtune->screen,
+ direction);
+ XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, True);
+ if (!result)
+ return;
+
+ UpdateCallback(w, call_data, client_data);
+
+ if (modeline.htotal && modeline.vtotal)
+ XmuSnprintf(label, sizeof(label), "%dx%d @ %d Hz",
+ modeline.hdisplay, modeline.vdisplay,
+ (int)((double)dot_clock / (double)modeline.htotal * 1000.0 /
+ (double)modeline.vtotal));
+ else
+ XmuSnprintf(label, sizeof(label), "%dx%d",
+ modeline.hdisplay, modeline.vdisplay);
+ XtSetArg(args[0], XtNlabel, label);
+ XtSetValues(mode, args, 1);
+}
+
+/*ARGSUSED*/
+static void
+UpdateCallback(Widget w, XtPointer call_data, XtPointer client_data)
+{
+ GetModeLine(True);
+ SetLabels();
+ SetLabelAndModeline();
+}
+
+static void
+SetLabels(void)
+{
+ SetLabel(HSYNCSTART, modeline.hsyncstart);
+ SetLabel(VSYNCSTART, modeline.vsyncstart);
+ SetLabel(HSYNCEND, modeline.hsyncend);
+ SetLabel(VSYNCEND, modeline.vsyncend);
+ SetLabel(HTOTAL, modeline.htotal);
+ SetLabel(VTOTAL, modeline.vtotal);
+ SetLabel(FLAGS, modeline.flags);
+ SetLabel(CLOCK, dot_clock);
+ UpdateSyncRates(True);
+}
+
+/*ARGSUSED*/
+static void
+ChangeScreenCallback(Widget w, XtPointer call_data, XtPointer client_data)
+{
+ Arg args[1];
+
+ screenno = (long)call_data;
+ if (screenno > computer.num_vidmodes || screenno < 0 ||
+ vidtune == computer.vidmodes[screenno])
+ return;
+
+ XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, False);
+ vidtune = computer.vidmodes[screenno];
+ XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, True);
+ UpdateCallback(w, call_data, client_data);
+ GetModes();
+
+ XtSetArg(args[0], XtNlabel, XtName(w));
+ XtSetValues(screenb, args, 1);
+
+ SetLabelAndModeline();
+}
+
+/*ARGSUSED*/
+static void
+SelectMonitorCallback(Widget w, XtPointer call_data, XtPointer client_data)
+{
+ vidtune->monitor = (XF86ConfMonitorPtr)(call_data);
+ SetLabelAndModeline();
+}
+
+/*ARGSUSED*/
+static void
+AddVesaModeCallback(Widget w, XtPointer call_data, XtPointer client_data)
+{
+ xf86cfgVesaModeInfo *vesa = (xf86cfgVesaModeInfo*)call_data;
+ XF86VidModeModeInfo mode;
+ int num_infos = vidtune->num_infos;
+
+ memcpy(&mode, &vesa->info, sizeof(XF86VidModeModeInfo));
+ if (XF86VidModeAddModeLine(XtDisplay(toplevel), vidtune->screen,
+ &vesa->info, &mode)) {
+ XSync(XtDisplay(toplevel), False);
+ GetModes();
+ }
+ else {
+ XBell(XtDisplayOfObject(w), 80);
+ return;
+ }
+
+ if (vidtune && num_infos == vidtune->num_infos) {
+ /* XF86VidModeAddModeLine returned True, but no modeline was added */
+ XBell(XtDisplayOfObject(w), 80);
+ if (vidtune->monitor && AddMode()) {
+ XF86ConfModeLinePtr mode;
+ char label[256], *ptr, *str;
+
+ XmuSnprintf(label, sizeof(label), "%s", vesa->ident);
+
+ /* format mode name to not have spaces */
+ ptr = strchr(label, ')');
+ if (ptr)
+ *++ptr = '\0';
+ ptr = str = label;
+ while (*ptr) {
+ if (*ptr != ' ')
+ *str++ = *ptr;
+ ++ptr;
+ }
+ *str = '\0';
+
+ if (xf86findModeLine(label, vidtune->monitor->mon_modeline_lst)
+ != NULL && !ForceAddMode())
+ return;
+
+ mode = (XF86ConfModeLinePtr)XtCalloc(1, sizeof(XF86ConfModeLineRec));
+ mode->ml_identifier = XtNewString(label);
+ mode->ml_clock = vesa->info.dotclock;
+ mode->ml_hdisplay = vesa->info.hdisplay;
+ mode->ml_hsyncstart = vesa->info.hsyncstart;
+ mode->ml_hsyncend = vesa->info.hsyncend;
+ mode->ml_htotal = vesa->info.htotal;
+ mode->ml_vdisplay = vesa->info.vdisplay;
+ mode->ml_vsyncstart = vesa->info.vsyncstart;
+ mode->ml_vsyncend = vesa->info.vsyncend;
+ mode->ml_vtotal = vesa->info.vtotal;
+/* mode->ml_vscan = ???;*/
+ mode->ml_flags = vesa->info.flags;
+ mode->ml_hskew = vesa->info.hskew;
+ vidtune->monitor->mon_modeline_lst =
+ xf86addModeLine(vidtune->monitor->mon_modeline_lst, mode);
+ }
+ }
+}
+
+static void
+GetModes(void)
+{
+ int i;
+ char label[32];
+ Arg args[1];
+ static char menuName[16];
+ static int menuN;
+
+ XFree(vidtune->infos);
+ XF86VidModeGetAllModeLines(XtDisplay(toplevel), vidtune->screen,
+ &vidtune->num_infos, &vidtune->infos);
+
+ XmuSnprintf(menuName, sizeof(menuName), "menu%d", menuN);
+ menuN = !menuN;
+ if (menu)
+ XtDestroyWidget(menu);
+ menu = XtCreatePopupShell(menuName, simpleMenuWidgetClass, vtune, NULL, 0);
+ XtVaSetValues(mode, XtNmenuName, menuName, NULL, 0);
+ for (i = 0; i < vidtune->num_infos; i++) {
+ Widget sme;
+
+ if ((double)vidtune->infos[i]->htotal &&
+ (double)vidtune->infos[i]->vtotal)
+ XmuSnprintf(label, sizeof(label), "%dx%d @ %d Hz",
+ vidtune->infos[i]->hdisplay,
+ vidtune->infos[i]->vdisplay,
+ (int)((double)vidtune->infos[i]->dotclock /
+ (double)vidtune->infos[i]->htotal * 1000.0 /
+ (double)vidtune->infos[i]->vtotal));
+ else
+ XmuSnprintf(label, sizeof(label), "%dx%d",
+ vidtune->infos[i]->hdisplay,
+ vidtune->infos[i]->vdisplay);
+ sme = XtCreateManagedWidget(label, smeBSBObjectClass, menu, NULL, 0);
+ XtAddCallback(sme, XtNcallback, SelectCallback,
+ (XtPointer)vidtune->infos[i]);
+ }
+
+ if (modeline.htotal && modeline.vtotal)
+ XmuSnprintf(label, sizeof(label), "%dx%d @ %d Hz",
+ modeline.hdisplay, modeline.vdisplay,
+ (int)((double)dot_clock / (double)modeline.htotal * 1000.0 /
+ (double)modeline.vtotal));
+ else
+ XmuSnprintf(label, sizeof(label), "%dx%d",
+ modeline.hdisplay, modeline.vdisplay);
+ XtSetArg(args[0], XtNlabel, label);
+ XtSetValues(mode, args, 1);
+}
+
+static int do_force, asking_force;
+
+static void
+PopdownForce(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ asking_force = 0;
+ XtPopdown(forceshell);
+ do_force = (long)user_data;
+}
+
+static int
+ForceAddMode(void)
+{
+ if (forceshell == NULL) {
+ Widget dialog;
+
+ forceshell = XtCreatePopupShell("force", transientShellWidgetClass,
+ toplevel, NULL, 0);
+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass,
+ forceshell, XtNvalue, NULL, NULL, 0);
+ XawDialogAddButton(dialog, "yes", PopdownForce, (XtPointer)True);
+ XawDialogAddButton(dialog, "no", PopdownForce, (XtPointer)False);
+ XtRealizeWidget(forceshell);
+ XSetWMProtocols(DPY, XtWindow(forceshell), &wm_delete_window, 1);
+ }
+
+ asking_force = 1;
+
+ XtPopup(forceshell, XtGrabExclusive);
+ while (asking_force)
+ XtAppProcessEvent(XtWidgetToApplicationContext(forceshell), XtIMAll);
+
+ return (do_force);
+}
+
+static int do_add, asking_add;
+
+static void
+PopdownAdd(Widget w, XtPointer user_data, XtPointer call_data)
+{
+ asking_add = 0;
+ XtPopdown(addshell);
+ do_add = (long)user_data;
+}
+
+void
+CancelAddModeAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ if (asking_force)
+ PopdownForce(w, (XtPointer)False, NULL);
+ else if (asking_add)
+ PopdownAdd(w, (XtPointer)False, NULL);
+}
+
+static int
+AddMode(void)
+{
+ if (addshell == NULL) {
+ Widget dialog;
+
+ addshell = XtCreatePopupShell("addMode", transientShellWidgetClass,
+ toplevel, NULL, 0);
+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass,
+ addshell, XtNvalue, NULL, NULL, 0);
+ XawDialogAddButton(dialog, "yes", PopdownAdd, (XtPointer)True);
+ XawDialogAddButton(dialog, "no", PopdownAdd, (XtPointer)False);
+ XtRealizeWidget(addshell);
+ XSetWMProtocols(DPY, XtWindow(addshell), &wm_delete_window, 1);
+ }
+
+ asking_add = 1;
+
+ XtPopup(addshell, XtGrabExclusive);
+ while (asking_add)
+ XtAppProcessEvent(XtWidgetToApplicationContext(addshell), XtIMAll);
+
+ return (do_add);
+}
+
+/*ARGSUSED*/
+static void
+AddModeCallback(Widget w, XtPointer call_data, XtPointer client_data)
+{
+ if (vidtune && vidtune->monitor) {
+ char *label;
+ Arg args[1];
+ XF86ConfModeLinePtr mode;
+
+ XtSetArg(args[0], XtNstring, &label);
+ XtGetValues(text, args, 1);
+ if (*label == '\0') {
+ XBell(XtDisplay(w), 80);
+ return;
+ }
+ if (xf86findModeLine(label, vidtune->monitor->mon_modeline_lst)
+ != NULL && !ForceAddMode())
+ return;
+
+ mode = (XF86ConfModeLinePtr)XtCalloc(1, sizeof(XF86ConfModeLineRec));
+ mode->ml_identifier = XtNewString(label);
+ mode->ml_clock = dot_clock;
+ mode->ml_hdisplay = modeline.hdisplay;
+ mode->ml_hsyncstart = modeline.hsyncstart;
+ mode->ml_hsyncend = modeline.hsyncend;
+ mode->ml_htotal = modeline.htotal;
+ mode->ml_vdisplay = modeline.vdisplay;
+ mode->ml_vsyncstart = modeline.vsyncstart;
+ mode->ml_vsyncend = modeline.vsyncend;
+ mode->ml_vtotal = modeline.vtotal;
+/* mode->ml_vscan = ???;*/
+ mode->ml_flags = modeline.flags;
+ mode->ml_hskew = modeline.hskew;
+ vidtune->monitor->mon_modeline_lst =
+ xf86addModeLine(vidtune->monitor->mon_modeline_lst, mode);
+ }
+ else
+ XBell(XtDisplay(w), 80);
+}
+
+/*ARGSUSED*/
+static void
+StopTestCallback(Widget w, XtPointer call_data, XtPointer client_data)
+{
+ XtRemoveTimeOut(timeout);
+ TestTimeout((XtPointer)w, NULL);
+}
+
+/*ARGSUSED*/
+void
+CancelTestModeAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ StopTestCallback(w, NULL, NULL);
+}
+
+static void
+TestTimeout(XtPointer client_data, XtIntervalId* id)
+{
+ XF86VidModeModeLine mode;
+
+ XtPopdown(testshell);
+ timeout = 0;
+ memcpy(&mode, &modeline, sizeof(XF86VidModeModeLine));
+ memcpy(&modeline, &orig_modeline, sizeof(XF86VidModeModeLine));
+ ApplyCallback((Widget)client_data, NULL, NULL);
+/* if (hitError == 0)*/
+ memcpy(&modeline, &mode, sizeof(XF86VidModeModeLine));
+ SetLabels();
+}
+
+static void
+TestCallback(Widget w, XtPointer call_data, XtPointer client_data)
+{
+ if (testshell == NULL) {
+ Widget dialog;
+
+ testshell = XtCreatePopupShell("test", transientShellWidgetClass,
+ toplevel, NULL, 0);
+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass,
+ testshell, XtNvalue, NULL, NULL, 0);
+ XawDialogAddButton(dialog, "stop", StopTestCallback, NULL);
+ XtRealizeWidget(testshell);
+ XSetWMProtocols(DPY, XtWindow(testshell), &wm_delete_window, 1);
+ }
+
+ XtPopup(testshell, XtGrabExclusive);
+
+ XSync(XtDisplay(toplevel), False);
+ timeout = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
+ /* the timeout probably shoud be converted to a resource */
+ 4000, TestTimeout, (XtPointer)w);
+ ApplyCallback(w, call_data, client_data);
+}
diff --git a/hw/xfree86/utils/xorgcfg/vidmode.h b/hw/xfree86/utils/xorgcfg/vidmode.h
new file mode 100644
index 000000000..e445517cd
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/vidmode.h
@@ -0,0 +1,64 @@
+/*
+ * 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/vidmode.h,v 1.3 2001/07/07 23:00:43 paulo Exp $
+ */
+
+#ifndef _xf86cfg_vidmode_h
+#define _xf86cfg_vidmode_h
+
+#include "xf86config.h"
+#include <X11/extensions/xf86vmode.h>
+
+/*
+ * Types
+ */
+struct _xf86cfgVidMode {
+ XF86ConfMonitorPtr monitor;
+ int screen;
+ int num_infos;
+ XF86VidModeModeInfo **infos;
+};
+
+/*
+ * Prototypes
+ */
+Bool VideoModeInitialize(void);
+void VideoModeConfigureStart(void);
+void VideoModeConfigureEnd(void);
+void VidmodeRestoreAction(Widget, XEvent*, String*, Cardinal*);
+void CancelAddModeAction(Widget, XEvent*, String*, Cardinal*);
+void CancelTestModeAction(Widget, XEvent*, String*, Cardinal*);
+void InitializeVidmodes(void);
+
+/*
+ * Initialization
+ */
+extern Widget vtune;
+
+#endif /* _xf86cfg_vidmode_h */
diff --git a/hw/xfree86/utils/xorgcfg/wider.xbm b/hw/xfree86/utils/xorgcfg/wider.xbm
new file mode 100644
index 000000000..5cf87f25a
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/wider.xbm
@@ -0,0 +1,8 @@
+#define wider_width 19
+#define wider_height 19
+static unsigned char wider_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0xc0, 0x18, 0x00,
+ 0xe0, 0x38, 0x00, 0xf0, 0x78, 0x00, 0xf8, 0xf8, 0x00, 0xfc, 0xff, 0x01,
+ 0xfe, 0xff, 0x03, 0xff, 0xff, 0x07, 0xfe, 0xff, 0x03, 0xfc, 0xff, 0x01,
+ 0xf8, 0xf8, 0x00, 0xf0, 0x78, 0x00, 0xe0, 0x38, 0x00, 0xc0, 0x18, 0x00,
+ 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/hw/xfree86/utils/xorgcfg/xf86config.c b/hw/xfree86/utils/xorgcfg/xf86config.c
new file mode 100644
index 000000000..b2b0b871c
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/xf86config.c
@@ -0,0 +1,980 @@
+/*
+ * 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/xf86config.c,v 1.5 2001/03/27 20:25:30 paulo Exp $
+ */
+
+#include "xf86config.h"
+
+/*
+ * Implementation
+ */
+int
+xf86removeOption(XF86OptionPtr *options, char *name)
+{
+ XF86OptionPtr opt = *options, prev = opt;
+
+ while (opt) {
+ if (strcasecmp(opt->opt_name, name) == 0) {
+ XtFree(opt->opt_name);
+ XtFree(opt->opt_val);
+ XtFree(opt->opt_comment);
+ if (opt == prev)
+ *options = (XF86OptionPtr)(opt->list.next);
+ else
+ prev->list.next = opt->list.next;
+ XtFree((XtPointer)opt);
+
+ return (True);
+ }
+
+ prev = opt;
+ opt = (XF86OptionPtr)(opt->list.next);
+ }
+
+ return (False);
+}
+
+int
+xf86removeInput(XF86ConfigPtr config, XF86ConfInputPtr input)
+{
+ XF86ConfInputPtr prev, inp = config->conf_input_lst;
+ XF86ConfLayoutPtr lay = config->conf_layout_lst;
+
+ /* remove from main structure */
+ prev = inp;
+ while (inp != NULL) {
+ if (inp == input) {
+ if (inp == prev)
+ config->conf_input_lst = (XF86ConfInputPtr)(inp->list.next);
+ else
+ prev->list.next = inp->list.next;
+ break;
+ }
+ prev = inp;
+ inp = (XF86ConfInputPtr)(inp->list.next);
+ }
+
+ if (inp == NULL)
+ return (False);
+
+ /* remove references */
+ while (lay != NULL) {
+ xf86removeInputRef(lay, inp);
+ lay = (XF86ConfLayoutPtr)(lay->list.next);
+ }
+
+ XtFree(inp->inp_identifier);
+ XtFree(inp->inp_driver);
+ XtFree(inp->inp_comment);
+ xf86optionListFree(inp->inp_option_lst);
+ XtFree((XtPointer)inp);
+
+ return (True);
+}
+
+int
+xf86removeInputRef(XF86ConfLayoutPtr layout, XF86ConfInputPtr input)
+{
+ XF86ConfInputrefPtr prev, iref = layout->lay_input_lst;
+
+ prev = iref;
+ while (iref != NULL) {
+ if (iref->iref_inputdev == input) {
+ XtFree(iref->iref_inputdev_str);
+ xf86optionListFree(iref->iref_option_lst);
+ if (prev == iref)
+ layout->lay_input_lst =
+ (XF86ConfInputrefPtr)(iref->list.next);
+ else
+ prev->list.next = iref->list.next;
+ XtFree((XtPointer)iref);
+
+ return (True);
+ }
+ prev = iref;
+ iref = (XF86ConfInputrefPtr)(iref->list.next);
+ }
+
+ return (False);
+}
+
+int
+xf86removeDevice(XF86ConfigPtr config, XF86ConfDevicePtr device)
+{
+ XF86ConfDevicePtr prev, dev = config->conf_device_lst;
+ XF86ConfScreenPtr psc, scr = config->conf_screen_lst;
+
+ /* remove from main structure */
+ prev = dev;
+ while (dev != NULL) {
+ if (dev == device) {
+ if (dev == prev)
+ config->conf_device_lst = (XF86ConfDevicePtr)(dev->list.next);
+ else
+ prev->list.next = dev->list.next;
+ break;
+ }
+ prev = dev;
+ dev = (XF86ConfDevicePtr)(dev->list.next);
+ }
+
+ if (dev == NULL)
+ return (False);
+
+ /* remove references */
+ psc = scr;
+ while (scr != NULL) {
+ if (scr->scrn_device == device) {
+ xf86removeScreen(config, scr);
+ if (scr == psc)
+ scr = psc = config->conf_screen_lst;
+ else
+ scr = psc;
+ continue;
+ }
+ psc = scr;
+ scr = (XF86ConfScreenPtr)(scr->list.next);
+ }
+
+ XtFree(dev->dev_identifier);
+ XtFree(dev->dev_vendor);
+ XtFree(dev->dev_board);
+ XtFree(dev->dev_chipset);
+ XtFree(dev->dev_busid);
+ XtFree(dev->dev_card);
+ XtFree(dev->dev_driver);
+ XtFree(dev->dev_ramdac);
+ XtFree(dev->dev_clockchip);
+ XtFree(dev->dev_comment);
+ xf86optionListFree(dev->dev_option_lst);
+ XtFree((XtPointer)dev);
+
+ return (True);
+}
+
+int
+xf86removeMonitor(XF86ConfigPtr config, XF86ConfMonitorPtr monitor)
+{
+ XF86ConfMonitorPtr prev, mon = config->conf_monitor_lst;
+ XF86ConfScreenPtr psc, scr = config->conf_screen_lst;
+
+ /* remove from main structure */
+ prev = mon;
+ while (mon != NULL) {
+ if (mon == monitor) {
+ if (mon == prev)
+ config->conf_monitor_lst = (XF86ConfMonitorPtr)(mon->list.next);
+ else
+ prev->list.next = mon->list.next;
+ break;
+ }
+ prev = mon;
+ mon = (XF86ConfMonitorPtr)(mon->list.next);
+ }
+
+ if (mon == NULL)
+ return (False);
+
+ /* remove references */
+ psc = scr;
+ while (scr != NULL) {
+ if (scr->scrn_monitor == monitor) {
+ xf86removeScreen(config, scr);
+ scr = psc = config->conf_screen_lst;
+ continue;
+ }
+ psc = scr;
+ scr = (XF86ConfScreenPtr)(scr->list.next);
+ }
+
+ XtFree(mon->mon_identifier);
+ XtFree(mon->mon_vendor);
+ XtFree(mon->mon_modelname);
+ XtFree(mon->mon_comment);
+ xf86optionListFree(mon->mon_option_lst);
+ XtFree((XtPointer)mon);
+
+ return (True);
+}
+
+int
+xf86removeScreen(XF86ConfigPtr config, XF86ConfScreenPtr screen)
+{
+ XF86ConfScreenPtr prev, scrn;
+ XF86ConfLayoutPtr lay;
+
+ if (config == NULL || screen == NULL)
+ return (False);
+
+ lay = config->conf_layout_lst;
+ prev = scrn = config->conf_screen_lst;
+
+ while (scrn != NULL) {
+ if (scrn == screen) {
+ if (scrn == prev)
+ config->conf_screen_lst = (XF86ConfScreenPtr)(scrn->list.next);
+ else
+ prev->list.next = scrn->list.next;
+ break;
+ }
+ prev = scrn;
+ scrn = (XF86ConfScreenPtr)(scrn->list.next);
+ }
+
+ if (scrn == NULL)
+ return (False);
+
+ while (lay != NULL) {
+ XF86ConfAdjacencyPtr pad, ad = NULL, adj = lay->lay_adjacency_lst;
+
+ pad = adj;
+ while (adj) {
+ if (adj->adj_screen == screen)
+ ad = adj;
+ else {
+ if (adj->adj_top != NULL && adj->adj_top == screen) {
+ XtFree(adj->adj_top_str);
+ adj->adj_top_str = NULL;
+ adj->adj_top = NULL;
+ }
+ else if (adj->adj_bottom != NULL && adj->adj_bottom == screen) {
+ XtFree(adj->adj_bottom_str);
+ adj->adj_bottom_str = NULL;
+ adj->adj_bottom = NULL;
+ }
+ else if (adj->adj_left != NULL && adj->adj_left == screen) {
+ XtFree(adj->adj_left_str);
+ adj->adj_left_str = NULL;
+ adj->adj_left = NULL;
+ }
+ else if (adj->adj_right != NULL && adj->adj_right == screen) {
+ XtFree(adj->adj_right_str);
+ adj->adj_right_str = NULL;
+ adj->adj_right = NULL;
+ }
+ else if (adj->adj_refscreen != NULL &&
+ strcasecmp(scrn->scrn_identifier,
+ adj->adj_refscreen) == 0) {
+ XtFree(adj->adj_refscreen);
+ adj->adj_refscreen = NULL;
+ adj->adj_where = CONF_ADJ_ABSOLUTE;
+ adj->adj_x = adj->adj_y = 0;
+ }
+ }
+ if (ad == NULL)
+ pad = adj;
+ adj = (XF86ConfAdjacencyPtr)(adj->list.next);
+ }
+
+ if (ad != NULL) {
+ if (ad == lay->lay_adjacency_lst)
+ lay->lay_adjacency_lst = (XF86ConfAdjacencyPtr)(ad->list.next);
+ else
+ pad->list.next = (XF86ConfAdjacencyPtr)(ad->list.next);
+ XtFree(ad->adj_screen_str);
+ XtFree(ad->adj_top_str);
+ XtFree(ad->adj_bottom_str);
+ XtFree(ad->adj_left_str);
+ XtFree(ad->adj_right_str);
+ XtFree(ad->adj_refscreen);
+ XtFree((XtPointer)ad);
+ }
+
+ lay = (XF86ConfLayoutPtr)(lay->list.next);
+ }
+
+ xf86freeAdaptorLinkList(screen->scrn_adaptor_lst);
+ xf86freeDisplayList(screen->scrn_display_lst);
+
+ XtFree(screen->scrn_identifier);
+ XtFree(screen->scrn_monitor_str);
+ XtFree(screen->scrn_device_str);
+ xf86optionListFree(screen->scrn_option_lst);
+ XtFree((XtPointer)screen);
+
+ return (True);
+}
+
+int
+xf86removeAdjacency(XF86ConfLayoutPtr layout, XF86ConfAdjacencyPtr adjacency)
+{
+ XF86ConfAdjacencyPtr prev, adj = layout->lay_adjacency_lst;
+
+ if (layout == NULL || adjacency == NULL)
+ return (False);
+
+ prev = adj;
+ while (adj != NULL) {
+ if (adj == adjacency)
+ break;
+ prev = adj;
+ adj = (XF86ConfAdjacencyPtr)(adj->list.next);
+ }
+ if (adj == NULL)
+ return (False);
+
+ XtFree(adj->adj_screen_str);
+ XtFree(adj->adj_top_str);
+ XtFree(adj->adj_bottom_str);
+ XtFree(adj->adj_left_str);
+ XtFree(adj->adj_right_str);
+ XtFree(adj->adj_refscreen);
+ if (prev == adj)
+ layout->lay_adjacency_lst = (XF86ConfAdjacencyPtr)(adj->list.next);
+ else
+ prev->list.next = adj->list.next;
+ XtFree((XtPointer)adj);
+
+ return (True);
+}
+
+int
+xf86removeInactive(XF86ConfLayoutPtr layout, XF86ConfInactivePtr inactive)
+{
+ XF86ConfInactivePtr prev, inac = layout->lay_inactive_lst;
+
+ if (layout == NULL || inactive == NULL)
+ return (False);
+
+ prev = inac;
+ while (inac != NULL) {
+ if (inac == inactive)
+ break;
+ prev = inac;
+ inac = (XF86ConfInactivePtr)(inac->list.next);
+ }
+ if (inac == NULL)
+ return (False);
+
+ XtFree(inac->inactive_device_str);
+ if (prev == inac)
+ layout->lay_inactive_lst = (XF86ConfInactivePtr)(inac->list.next);
+ else
+ prev->list.next = inac->list.next;
+ XtFree((XtPointer)inac);
+
+ return (True);
+}
+
+int
+xf86removeLayout(XF86ConfigPtr config, XF86ConfLayoutPtr layout)
+{
+ XF86ConfLayoutPtr prev, lay = config->conf_layout_lst;
+ XF86ConfAdjacencyPtr adj, nadj;
+ XF86ConfInactivePtr inac, ninac;
+ XF86ConfInputrefPtr iref, niref;
+
+ if (config == NULL || layout == NULL)
+ return (False);
+
+ prev = lay;
+ while (lay != NULL) {
+ if (lay == layout)
+ break;
+ prev = lay;
+ lay = (XF86ConfLayoutPtr)(lay->list.next);
+ }
+
+ if (lay == NULL)
+ return (False);
+
+ adj = lay->lay_adjacency_lst;
+ while (adj != NULL) {
+ nadj = (XF86ConfAdjacencyPtr)(adj->list.next);
+ xf86removeAdjacency(lay, adj);
+ adj = nadj;
+ }
+
+ inac = lay->lay_inactive_lst;
+ while (inac != NULL) {
+ ninac = (XF86ConfInactivePtr)(inac->list.next);
+ xf86removeInactive(lay, inac);
+ inac = ninac;
+ }
+
+ iref = lay->lay_input_lst;
+ while (iref != NULL) {
+ niref = (XF86ConfInputrefPtr)(iref->list.next);
+ xf86removeInputRef(lay, iref->iref_inputdev);
+ iref = niref;
+ }
+
+ xf86optionListFree(lay->lay_option_lst);
+
+ if (prev == lay)
+ config->conf_layout_lst = (XF86ConfLayoutPtr)(lay->list.next);
+ else
+ prev->list.next = lay->list.next;
+ XtFree(lay->lay_identifier);
+ XtFree((XtPointer)lay);
+
+ return (True);
+}
+
+int
+xf86removeModule(XF86ConfigPtr config, XF86LoadPtr load)
+{
+ XF86LoadPtr prev, mod;
+
+ if (config == NULL || config->conf_modules == NULL ||
+ config->conf_modules->mod_load_lst == NULL)
+ return (False);
+
+ for (mod = prev = config->conf_modules->mod_load_lst;
+ mod != NULL; prev = mod, mod = (XF86LoadPtr)(mod->list.next))
+ if (load == mod) {
+ if (mod == prev)
+ config->conf_modules->mod_load_lst =
+ (XF86LoadPtr)(mod->list.next);
+ else
+ prev->list.next = mod->list.next;
+ XtFree(mod->load_name);
+ xf86optionListFree(mod->load_opt);
+
+ return (True);
+ }
+
+ return (False);
+}
+
+int
+xf86removeModes(XF86ConfigPtr config, XF86ConfModesPtr modes)
+{
+ XF86ConfModesPtr mod;
+ XF86ConfModeLinePtr ml, next;
+ XF86ConfMonitorPtr mon;
+
+ if (config == NULL || modes == NULL)
+ return (False);
+
+ /* check if modes is in config */
+ if ((mod = config->conf_modes_lst) == modes)
+ config->conf_modes_lst = (XF86ConfModesPtr)(mod->list.next);
+ else
+ for (; mod != NULL; mod = (XF86ConfModesPtr)(mod->list.next))
+ if ((XF86ConfModesPtr)(mod->list.next) == modes) {
+ mod->list.next = modes->list.next;
+ break;
+ }
+
+ if (mod == NULL)
+ return (False);
+
+ /* remove references in monitor sections */
+ mon = config->conf_monitor_lst;
+ while (mon) {
+ XF86ConfModesLinkPtr m, p;
+
+ m = p = mon->mon_modes_sect_lst;
+ while (m) {
+ if (m->ml_modes == modes) {
+ XtFree(m->ml_modes_str);
+ if (m == mon->mon_modes_sect_lst)
+ p = mon->mon_modes_sect_lst =
+ (XF86ConfModesLinkPtr)(m->list.next);
+ else {
+ p->list.next = m->list.next;
+ p = p->list.next;
+ }
+ XtFree((XtPointer)m);
+ m = p;
+ continue;
+ }
+ p = m;
+ m = (XF86ConfModesLinkPtr)(m->list.next);
+ }
+ mon = (XF86ConfMonitorPtr)(mon->list.next);
+ }
+
+ /* free modelines */
+ ml = modes->mon_modeline_lst;
+ while (ml) {
+ next = (XF86ConfModeLinePtr)(ml->list.next);
+ XtFree(ml->ml_identifier);
+ XtFree((XtPointer)ml);
+ ml = next;
+ }
+
+ /* free mode */
+ XtFree(modes->modes_identifier);
+ XtFree((XtPointer)modes);
+
+ return (True);
+}
+
+int
+xf86removeModesModeLine(XF86ConfModesPtr modes, XF86ConfModeLinePtr modeline)
+{
+ XF86ConfModeLinePtr ml, prev;
+
+ if (modes == NULL || modeline == NULL || modes->mon_modeline_lst == NULL)
+ return (False);
+
+ for (ml = prev = modes->mon_modeline_lst; ml;
+ prev = ml, ml = (XF86ConfModeLinePtr)(ml->list.next))
+ if (ml == modeline) {
+ if (prev == ml)
+ modes->mon_modeline_lst = (XF86ConfModeLinePtr)(ml->list.next);
+ else
+ prev->list.next = ml->list.next;
+ XtFree(modeline->ml_identifier);
+ XtFree((XtPointer)modeline);
+ return (True);
+ }
+
+ return (False);
+}
+
+int
+xf86removeMonitorModeLine(XF86ConfMonitorPtr monitor, XF86ConfModeLinePtr modeline)
+{
+ XF86ConfModeLinePtr ml, prev;
+
+ if (monitor == NULL || modeline == NULL || monitor->mon_modeline_lst == NULL)
+ return (False);
+
+ for (ml = prev = monitor->mon_modeline_lst; ml;
+ prev = ml, ml = (XF86ConfModeLinePtr)(ml->list.next))
+ if (ml == modeline) {
+ if (prev == ml)
+ monitor->mon_modeline_lst = (XF86ConfModeLinePtr)(ml->list.next);
+ else
+ prev->list.next = ml->list.next;
+ XtFree(modeline->ml_identifier);
+ XtFree((XtPointer)modeline);
+ return (True);
+ }
+
+ return (False);
+}
+
+int
+xf86removeMonitorModesLink(XF86ConfMonitorPtr monitor, XF86ConfModesLinkPtr link)
+{
+ XF86ConfModesLinkPtr lnk, prev;
+
+ if (monitor == NULL || link == NULL || monitor->mon_modes_sect_lst == NULL)
+ return (False);
+
+ for (lnk = prev = monitor->mon_modes_sect_lst; lnk != NULL;
+ prev = lnk, lnk = (XF86ConfModesLinkPtr)(lnk->list.next))
+ if (lnk == link) {
+ if (prev == lnk)
+ monitor->mon_modes_sect_lst = (XF86ConfModesLinkPtr)(lnk->list.next);
+ else
+ prev->list.next = lnk->list.next;
+ XtFree(link->ml_modes_str);
+ XtFree((XtPointer)link);
+
+ return (True);
+ }
+
+ return (False);
+}
+
+int
+xf86removeScreenAdaptorLink(XF86ConfScreenPtr scrn, XF86ConfAdaptorLinkPtr link)
+{
+ XF86ConfAdaptorLinkPtr lnk, prev;
+
+ if (scrn == NULL || link == NULL || scrn->scrn_adaptor_lst == NULL)
+ return (False);
+
+ for (lnk = prev = scrn->scrn_adaptor_lst; lnk != NULL;
+ prev = lnk, lnk = (XF86ConfAdaptorLinkPtr)(lnk->list.next))
+ if (lnk == link) {
+ if (prev == lnk)
+ scrn->scrn_adaptor_lst =
+ (XF86ConfAdaptorLinkPtr)(lnk->list.next);
+ else
+ prev->list.next = lnk->list.next;
+ XtFree(link->al_adaptor_str);
+ XtFree((XtPointer)link);
+
+ return (True);
+ }
+
+ return (False);
+}
+
+int
+xf86removeScreenDisplay(XF86ConfScreenPtr scrn, XF86ConfDisplayPtr display)
+{
+ XF86ConfDisplayPtr dsp, prev;
+
+ if (scrn == NULL || display == NULL || scrn->scrn_display_lst == NULL)
+ return (False);
+
+ for (dsp = prev = scrn->scrn_display_lst; dsp != NULL;
+ prev = dsp, dsp = (XF86ConfDisplayPtr)(dsp->list.next))
+ if (dsp == display) {
+ if (prev == dsp)
+ scrn->scrn_display_lst =
+ (XF86ConfDisplayPtr)(dsp->list.next);
+ else
+ prev->list.next = dsp->list.next;
+ xf86optionListFree(display->disp_option_lst);
+ XtFree((XtPointer)display->disp_visual);
+ xf86freeModeList(display->disp_mode_lst);
+ XtFree((XtPointer)display);
+
+ return (True);
+ }
+
+ return (False);
+}
+
+int
+xf86removeVideoAdaptor(XF86ConfigPtr config, XF86ConfVideoAdaptorPtr video)
+{
+ XF86ConfVideoAdaptorPtr vid;
+ XF86ConfScreenPtr scrn;
+ XF86ConfVideoPortPtr vp, next;
+
+ if (config == NULL || video == NULL)
+ return (False);
+
+ /* check if video is in config and update videoadaptor list */
+ if ((vid = config->conf_videoadaptor_lst) == video)
+ config->conf_videoadaptor_lst = (XF86ConfVideoAdaptorPtr)(vid->list.next);
+ else
+ for (; vid != NULL; vid = (XF86ConfVideoAdaptorPtr)(vid->list.next))
+ if ((XF86ConfVideoAdaptorPtr)(vid->list.next) == video) {
+ vid->list.next = video->list.next;
+ break;
+ }
+
+ if (vid == NULL)
+ return (False);
+
+ /* remove references in screen sections */
+ scrn = config->conf_screen_lst;
+ while (scrn) {
+ XF86ConfAdaptorLinkPtr v, p;
+
+ v = p = scrn->scrn_adaptor_lst;
+ while (v) {
+ if (v->al_adaptor == video) {
+ XtFree(v->al_adaptor_str);
+ if (v == scrn->scrn_adaptor_lst)
+ p = scrn->scrn_adaptor_lst =
+ (XF86ConfAdaptorLinkPtr)(v->list.next);
+ else {
+ p->list.next = v->list.next;
+ p = p->list.next;
+ }
+ XtFree((XtPointer)v);
+ v = p;
+ continue;
+ }
+ p = v;
+ v = (XF86ConfAdaptorLinkPtr)(v->list.next);
+ }
+ scrn = (XF86ConfScreenPtr)(scrn->list.next);
+ }
+
+ /* free videoports */
+ vp = video->va_port_lst;
+ while (vp) {
+ next = (XF86ConfVideoPortPtr)(vp->list.next);
+ XtFree(vp->vp_identifier);
+ xf86optionListFree(vp->vp_option_lst);
+ XtFree((XtPointer)vp);
+ vp = next;
+ }
+
+ /* free videoadaptor */
+ XtFree(video->va_identifier);
+ XtFree(video->va_vendor);
+ XtFree(video->va_board);
+ XtFree(video->va_busid);
+ XtFree(video->va_driver);
+ XtFree(video->va_fwdref);
+ xf86optionListFree(video->va_option_lst);
+ XtFree((XtPointer)video);
+
+ return (True);
+}
+
+int
+xf86removeVideoPort(XF86ConfVideoAdaptorPtr va, XF86ConfVideoPortPtr vp)
+{
+ XF86ConfVideoPortPtr prev;
+
+ if (va == NULL || vp == NULL)
+ return (False);
+
+ if ((prev = va->va_port_lst) == vp)
+ va->va_port_lst = (XF86ConfVideoPortPtr)(va->va_port_lst->list.next);
+ else {
+ while (prev && (XF86ConfVideoPortPtr)(prev->list.next) != vp)
+ prev = (XF86ConfVideoPortPtr)(prev->list.next);
+ if (prev == NULL)
+ return (False);
+ prev->list.next = vp->list.next;
+ }
+
+ xf86optionListFree(vp->vp_option_lst);
+ XtFree((XtPointer)vp);
+
+ return (True);
+}
+
+int
+xf86removeDisplayMode(XF86ConfDisplayPtr display, XF86ModePtr mode)
+{
+ XF86ModePtr prev;
+
+ if (display == NULL || mode == NULL)
+ return (False);
+
+ if ((prev = display->disp_mode_lst) == mode)
+ display->disp_mode_lst = (XF86ModePtr)(display->disp_mode_lst->list.next);
+ else {
+ while (prev && (XF86ModePtr)(prev->list.next) != mode)
+ prev = (XF86ModePtr)(prev->list.next);
+ if (prev == NULL)
+ return (False);
+ prev->list.next = mode->list.next;
+ }
+
+ XtFree((XtPointer)mode);
+
+ return (True);
+}
+
+int
+xf86removeVendor(XF86ConfigPtr config, XF86ConfVendorPtr vendor)
+{
+ XF86ConfVendorPtr prev;
+
+ if (config == NULL || vendor == NULL)
+ return (False);
+
+ if ((prev = config->conf_vendor_lst) == vendor)
+ config->conf_vendor_lst = (XF86ConfVendorPtr)(config->conf_vendor_lst->list.next);
+ else {
+ while (prev && (XF86ConfVendorPtr)(prev->list.next) != vendor)
+ prev = (XF86ConfVendorPtr)(prev->list.next);
+ if (prev == NULL)
+ return (False);
+ prev->list.next = vendor->list.next;
+ }
+
+ xf86optionListFree(vendor->vnd_option_lst);
+ xf86freeVendorSubList(vendor->vnd_sub_lst);
+ XtFree(vendor->vnd_identifier);
+ XtFree((XtPointer)vendor);
+
+ return (True);
+}
+
+int
+xf86removeVendorSub(XF86ConfVendorPtr vendor, XF86ConfVendSubPtr sub)
+{
+ XF86ConfVendSubPtr prev;
+
+ if (vendor == NULL || sub == NULL)
+ return (False);
+
+ if ((prev = vendor->vnd_sub_lst) == sub)
+ vendor->vnd_sub_lst = (XF86ConfVendSubPtr)(vendor->vnd_sub_lst->list.next);
+ else {
+ while (prev && (XF86ConfVendSubPtr)(prev->list.next) != sub)
+ prev = (XF86ConfVendSubPtr)(prev->list.next);
+ if (prev == NULL)
+ return (False);
+ prev->list.next = sub->list.next;
+ }
+
+ xf86optionListFree(sub->vs_option_lst);
+ XtFree(sub->vs_name);
+ XtFree(sub->vs_identifier);
+ XtFree((XtPointer)sub);
+
+ return (True);
+}
+
+int
+xf86removeBuffers(XF86ConfDRIPtr dri, XF86ConfBuffersPtr buf)
+{
+ XF86ConfBuffersPtr prev;
+
+ if (dri == NULL || buf == NULL)
+ return (False);
+
+ if ((prev = dri->dri_buffers_lst) == buf)
+ dri->dri_buffers_lst = (XF86ConfBuffersPtr)(dri->dri_buffers_lst->list.next);
+ else {
+ while (prev && (XF86ConfBuffersPtr)(prev->list.next) != buf)
+ prev = (XF86ConfBuffersPtr)(prev->list.next);
+ if (prev == NULL)
+ return (False);
+ prev->list.next = buf->list.next;
+ }
+
+ XtFree(buf->buf_flags);
+ XtFree((XtPointer)buf);
+
+ return (True);
+}
+
+int
+xf86renameInput(XF86ConfigPtr config, XF86ConfInputPtr input, char *name)
+{
+ XF86ConfLayoutPtr lay = config->conf_layout_lst;
+
+ if (config == NULL || input == NULL || name == NULL || *name == '\0')
+ return (False);
+
+ while (lay != NULL) {
+ XF86ConfInputrefPtr iref = lay->lay_input_lst;
+
+ while (iref != NULL) {
+ if (strcasecmp(input->inp_identifier, iref->iref_inputdev_str) == 0) {
+ XtFree(iref->iref_inputdev_str);
+ iref->iref_inputdev_str = XtNewString(name);
+ }
+ iref = (XF86ConfInputrefPtr)(iref->list.next);
+ }
+ lay = (XF86ConfLayoutPtr)(lay->list.next);
+ }
+
+ XtFree(input->inp_identifier);
+ input->inp_identifier = XtNewString(name);
+
+ return (True);
+}
+
+int
+xf86renameDevice(XF86ConfigPtr config, XF86ConfDevicePtr dev, char *name)
+{
+ XF86ConfScreenPtr scr = config->conf_screen_lst;
+
+ if (config == NULL || dev == NULL || name == NULL || *name == '\0')
+ return (False);
+
+ while (scr != NULL) {
+ if (scr->scrn_device == dev) {
+ XtFree(scr->scrn_device_str);
+ scr->scrn_device_str = XtNewString(name);
+ }
+
+ scr = (XF86ConfScreenPtr)(scr->list.next);
+ }
+
+ XtFree(dev->dev_identifier);
+ dev->dev_identifier = XtNewString(name);
+
+ return (True);
+}
+
+int
+xf86renameMonitor(XF86ConfigPtr config, XF86ConfMonitorPtr mon, char *name)
+{
+ XF86ConfScreenPtr scr = config->conf_screen_lst;
+
+ if (config == NULL || mon == NULL || name == NULL || *name == '\0')
+ return (False);
+
+ while (scr != NULL) {
+ if (scr->scrn_monitor == mon) {
+ XtFree(scr->scrn_monitor_str);
+ scr->scrn_monitor_str = XtNewString(name);
+ }
+
+ scr = (XF86ConfScreenPtr)(scr->list.next);
+ }
+
+ XtFree(mon->mon_identifier);
+ mon->mon_identifier = XtNewString(name);
+
+ return (True);
+}
+
+int
+xf86renameLayout(XF86ConfigPtr config, XF86ConfLayoutPtr layout, char *name)
+{
+ if (config == NULL || layout == NULL || name == NULL || *name == '\0')
+ return (False);
+
+ XtFree(layout->lay_identifier);
+ layout->lay_identifier = XtNewString(name);
+
+ return (True);
+}
+
+int
+xf86renameScreen(XF86ConfigPtr config, XF86ConfScreenPtr scrn, char *name)
+{
+ XF86ConfLayoutPtr lay = config->conf_layout_lst;
+
+ if (config == NULL || scrn == NULL || name == NULL || *name == '\0')
+ return (False);
+
+ while (lay != NULL) {
+ XF86ConfAdjacencyPtr adj = lay->lay_adjacency_lst;
+
+ while (adj != NULL) {
+ if (adj->adj_screen == scrn) {
+ XtFree(adj->adj_screen_str);
+ adj->adj_screen_str = XtNewString(name);
+ }
+ else if (adj->adj_top == scrn) {
+ XtFree(adj->adj_top_str);
+ adj->adj_top_str = XtNewString(name);
+ }
+ else if (adj->adj_bottom == scrn) {
+ XtFree(adj->adj_bottom_str);
+ adj->adj_bottom_str = XtNewString(name);
+ }
+ else if (adj->adj_left == scrn) {
+ XtFree(adj->adj_left_str);
+ adj->adj_left_str = XtNewString(name);
+ }
+ else if (adj->adj_right == scrn) {
+ XtFree(adj->adj_right_str);
+ adj->adj_right_str = XtNewString(name);
+ }
+ else if (adj->adj_refscreen != NULL &&
+ strcasecmp(adj->adj_refscreen, name) == 0) {
+ XtFree(adj->adj_refscreen);
+ adj->adj_refscreen = XtNewString(name);
+ }
+
+ adj = (XF86ConfAdjacencyPtr)(adj->list.next);
+ }
+ lay = (XF86ConfLayoutPtr)(lay->list.next);
+ }
+
+ XtFree(scrn->scrn_identifier);
+ scrn->scrn_identifier = XtNewString(name);
+
+ return (True);
+}
diff --git a/hw/xfree86/utils/xorgcfg/xf86config.h b/hw/xfree86/utils/xorgcfg/xf86config.h
new file mode 100644
index 000000000..575c3c9d0
--- /dev/null
+++ b/hw/xfree86/utils/xorgcfg/xf86config.h
@@ -0,0 +1,111 @@
+/*
+ * 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/xf86config.h,v 1.4 2000/11/30 20:55:18 paulo Exp $
+ */
+
+#include "config.h"
+
+#ifndef _xf86cfg_xf86config_h
+#define _xf86cfg_xf86config_h
+
+#define xf86addInput(head, ptr) \
+ (XF86ConfInputPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addInputref(head, ptr) \
+ (XF86ConfInputrefPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addDevice(head, ptr) \
+ (XF86ConfDevicePtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addDisplayMode(head, ptr) \
+ (XF86ModePtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addMonitor(head, ptr) \
+ (XF86ConfMonitorPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addScreen(head, ptr) \
+ (XF86ConfScreenPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addLayout(head, ptr) \
+ (XF86ConfLayoutPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addModeLine(head, ptr) \
+ (XF86ConfModeLinePtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addModes(head, ptr) \
+ (XF86ConfModesPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addModesLink(head, ptr) \
+ (XF86ConfModesLinkPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addModule(head, ptr) \
+ (XF86LoadPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addScreenAdaptor(head, ptr) \
+ (XF86ConfAdaptorLinkPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addScreenDisplay(head, ptr) \
+ (XF86ConfDisplayPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addVideoAdaptor(head, ptr) \
+ (XF86ConfVideoAdaptorPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addVideoPort(head, ptr) \
+ (XF86ConfVideoPortPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addAdjacency(head, ptr) \
+ (XF86ConfAdjacencyPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addVendor(head, ptr) \
+ (XF86ConfVendorPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addVendorSub(head, ptr) \
+ (XF86ConfVendSubPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+#define xf86addBuffers(head, ptr) \
+ (XF86ConfBuffersPtr)xf86addListItem((GenericListPtr)(head), (GenericListPtr)(ptr))
+
+
+int xf86removeOption(XF86OptionPtr*, char*);
+int xf86removeInput(XF86ConfigPtr, XF86ConfInputPtr);
+int xf86removeInputRef(XF86ConfLayoutPtr, XF86ConfInputPtr);
+int xf86removeDevice(XF86ConfigPtr, XF86ConfDevicePtr);
+int xf86removeDisplayMode(XF86ConfDisplayPtr, XF86ModePtr);
+int xf86removeMonitor(XF86ConfigPtr, XF86ConfMonitorPtr);
+int xf86removeScreen(XF86ConfigPtr, XF86ConfScreenPtr);
+int xf86removeAdjacency(XF86ConfLayoutPtr, XF86ConfAdjacencyPtr);
+int xf86removeInactive(XF86ConfLayoutPtr, XF86ConfInactivePtr);
+int xf86removeLayout(XF86ConfigPtr, XF86ConfLayoutPtr);
+int xf86removeModule(XF86ConfigPtr, XF86LoadPtr);
+int xf86removeModes(XF86ConfigPtr, XF86ConfModesPtr);
+int xf86removeModesModeLine(XF86ConfModesPtr, XF86ConfModeLinePtr);
+int xf86removeMonitorModeLine(XF86ConfMonitorPtr, XF86ConfModeLinePtr);
+int xf86removeMonitorModesLink(XF86ConfMonitorPtr, XF86ConfModesLinkPtr);
+int xf86removeScreenAdaptorLink(XF86ConfScreenPtr, XF86ConfAdaptorLinkPtr);
+int xf86removeScreenDisplay(XF86ConfScreenPtr, XF86ConfDisplayPtr);
+int xf86removeVideoAdaptor(XF86ConfigPtr, XF86ConfVideoAdaptorPtr);
+int xf86removeVideoPort(XF86ConfVideoAdaptorPtr, XF86ConfVideoPortPtr);
+int xf86removeVendor(XF86ConfigPtr, XF86ConfVendorPtr);
+int xf86removeVendorSub(XF86ConfVendorPtr, XF86ConfVendSubPtr);
+int xf86removeBuffers(XF86ConfDRIPtr, XF86ConfBuffersPtr);
+
+int xf86renameInput(XF86ConfigPtr, XF86ConfInputPtr, char*);
+int xf86renameDevice(XF86ConfigPtr, XF86ConfDevicePtr, char*);
+int xf86renameMonitor(XF86ConfigPtr, XF86ConfMonitorPtr, char*);
+int xf86renameLayout(XF86ConfigPtr, XF86ConfLayoutPtr, char*);
+int xf86renameScreen(XF86ConfigPtr, XF86ConfScreenPtr, char*);
+
+extern void xf86freeAdaptorLinkList(XF86ConfAdaptorLinkPtr);
+extern void xf86freeDisplayList(XF86ConfDisplayPtr);
+extern void xf86freeModeList(XF86ModePtr);
+extern void xf86freeVendorSubList(XF86ConfVendSubPtr);
+
+#endif /* _xf86cfg_xf86config_h */