summaryrefslogtreecommitdiff
path: root/hw/xfree86/utils/xorgcfg/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xfree86/utils/xorgcfg/interface.c')
-rw-r--r--hw/xfree86/utils/xorgcfg/interface.c2280
1 files changed, 2280 insertions, 0 deletions
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();
+}