1
/* $XdotOrg: xserver/xorg/hw/xfree86/utils/xorgcfg/text-mode.c,v 1.6 2005/12/08 17:54:40 kem Exp $ */
3
* Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
5
* Permission is hereby granted, free of charge, to any person obtaining a
6
* copy of this software and associated documentation files (the "Software"),
7
* to deal in the Software without restriction, including without limitation
8
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
* and/or sell copies of the Software, and to permit persons to whom the
10
* Software is furnished to do so, subject to the following conditions:
12
* The above copyright notice and this permission notice shall be included in
13
* all copies or substantial portions of the Software.
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* CONECTIVA LINUX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
* Except as contained in this notice, the name of Conectiva Linux shall
24
* not be used in advertising or otherwise to promote the sale, use or other
25
* dealings in this Software without prior written authorization from
28
* Author: Paulo CĆ©sar Pereira de Andrade <pcpa@conectiva.com.br>
30
* $XFree86: xc/programs/Xserver/hw/xfree86/xf86cfg/text-mode.c,v 1.25 2003/11/12 00:10:30 dawes Exp $
36
#if defined(__SCO__) || defined(__UNIXWARE__) || \
37
(defined(sun) && defined(__SVR4))
44
#include <X11/extensions/XKBstr.h>
45
#include <X11/extensions/XKBrules.h>
48
#include "xf86config.h"
51
#define IS_KBDDRIV(X) ((strcmp((X),"kbd") == 0) || \
52
(strcmp((X), "keyboard") == 0))
55
#define PROJECT_ROOT "/usr/X11R6"
60
#define XKB_RULES_DIR PROJECT_ROOT "/lib/X11/xkb/rules"
62
#define XKB_RULES_DIR XF86CONFIGDIR "/xkb/rules"
71
#define MIN(a, b) ((a) < (b) ? (a) : (b))
72
#define MAX(a, b) ((a) > (b) ? (a) : (b))
76
static void ClearScreen(void);
77
static void PaintWindow(WINDOW*, char*, int, int, int, int);
78
static void PaintBox(WINDOW*, int, int, int, int);
79
static void PaintButton(WINDOW*, char*, int, int, int);
80
static void PrintWrap(WINDOW*, char*, int, int, int);
81
static int Dialog(char*, char*, int, int, char*, char*, int);
82
static void PaintItem(WINDOW*, char*, int, int);
83
static int DialogMenu(char*, char*, int, int, int, int, char**, char*, char*, int);
84
static void PaintCheckItem(WINDOW*, char*, int, int, int);
85
static int DialogCheckBox(char*, char*, int, int, int, int, char**, char*, char*, char*);
86
static char *DialogInput(char*, char*, int, int, char*, char*, char*, int);
87
static void PaintScroller(WINDOW*, int, int, int);
89
static int MouseConfig(void);
90
static int KeyboardConfig(void);
91
static int MonitorConfig(void);
92
static int CardConfig(void);
93
static int ScreenConfig(void);
94
static int LayoutConfig(void);
95
static int WriteXF86Config(void);
97
static XF86ConfLayoutPtr CopyLayout(XF86ConfLayoutPtr);
98
static XF86ConfAdjacencyPtr CopyAdjacency(XF86ConfAdjacencyPtr);
99
static XF86ConfInputrefPtr CopyInputref(XF86ConfInputrefPtr);
100
static XF86ConfInactivePtr CopyInactive(XF86ConfInactivePtr);
101
static void FreeLayout(XF86ConfLayoutPtr);
103
extern int string_to_parser_range(char*, parser_range*, int);
104
#define PARSER_RANGE_SIZE 256
105
/* string must have at least 256 bytes */
106
extern int parser_range_to_string(char*, parser_range*, int);
108
static Bool newconfig;
110
static chtype screen_attr = A_NORMAL;
111
static chtype dialog_attr = A_REVERSE;
112
static chtype highlight_border_attr = A_REVERSE;
113
static chtype shadow_border_attr = A_REVERSE;
114
static chtype title_attr = A_NORMAL;
115
static chtype button_active_attr = A_NORMAL;
116
static chtype button_inactive_attr = A_NORMAL;
117
static int menu_width, item_x;
118
static char Edit[] = "Edit ";
120
static char *main_menu[] = {
123
#define CONF_KEYBOARD 1
124
"Configure keyboard",
125
#define CONF_MONITOR 2
129
#define CONF_SCREEN 4
131
#define CONF_LAYOUT 5
133
#define CONF_FINISH 6
134
"Write "__XCONFIGFILE__" and quit",
142
static int first = 1;
143
int i, choice = CONF_MOUSE;
147
LoaderInitializeOptions();
152
keypad(stdscr, TRUE);
155
const char *filename;
161
init_pair(1, COLOR_BLACK, COLOR_BLACK);
162
screen_attr = A_BOLD | COLOR_PAIR(1);
164
init_pair(2, COLOR_BLACK, COLOR_WHITE);
165
dialog_attr = COLOR_PAIR(2);
167
init_pair(3, COLOR_BLACK, COLOR_WHITE);
168
shadow_border_attr = A_BOLD | COLOR_PAIR(3);
170
init_pair(4, COLOR_WHITE, COLOR_WHITE);
171
highlight_border_attr = A_BOLD | COLOR_PAIR(4);
173
init_pair(5, COLOR_WHITE, COLOR_BLUE);
174
title_attr = A_BOLD | COLOR_PAIR(5);
175
button_active_attr = title_attr;
177
init_pair(6, COLOR_WHITE, COLOR_BLACK);
178
button_inactive_attr = A_BOLD | COLOR_PAIR(6);
181
if ((filename = xf86openConfigFile(getuid() == 0 ?
182
CONFPATH : USER_CONFPATH,
183
XF86Config_path, NULL)) != NULL) {
184
XF86Config_path = (char *)filename;
185
if ((XF86Config = xf86readConfigFile()) == NULL) {
188
Dialog("Configuration error",
189
"Error parsing configuration file.",
190
7, 50, " Ok ", NULL, 0);
193
if (XF86Config == NULL) {
194
XF86Config = (XF86ConfigPtr)XtCalloc(1, sizeof(XF86ConfigRec));
210
if (Dialog( __XSERVERNAME__" Configuration",
211
"This program will create the "__XCONFIGFILE__" file, based on "
212
"menu selections you make.\n"
214
#if defined(__SCO__) || defined(__UNIXWARE__)
215
"The "__XCONFIGFILE__" file usually resides in /etc. A "
216
"sample "__XCONFIGFILE__" file is supplied with "
219
"The "__XCONFIGFILE__" file usually resides in " PROJECT_ROOT "/etc/X11 "
221
"The "__XCONFIGFILE__" file usually resides in "XF86CONFIGDIR" "
223
"or /etc/X11. A sample "__XCONFIGFILE__" file is supplied with "
225
__XSERVERNAME__"; it is configured for a standard VGA card and "
226
"monitor with 640x480 resolution. This program will ask for "
227
"a pathname when it is ready to write the file.\n"
229
"You can either take the sample "__XCONFIGFILE__" as a base and "
230
"edit it for your configuration, or let this program "
231
"produce a base "__XCONFIGFILE__" file for your configuration and "
233
20, 60, " Ok ", " Cancel ", 0) != 0)
239
switch (DialogMenu("Main menu",
240
"Choose one of the options:",
241
17, 60, 8, sizeof(main_menu) /
242
sizeof(main_menu[0]), main_menu,
243
" Ok ", " Cancel ", choice)) {
246
if (i > 0 && choice == CONF_MOUSE)
247
choice = CONF_KEYBOARD;
252
i = KeyboardConfig();
253
if (i > 0 && choice <= CONF_KEYBOARD)
254
choice = CONF_MONITOR;
256
choice = CONF_KEYBOARD;
260
if (i > 0 && choice <= CONF_MONITOR)
263
choice = CONF_MONITOR;
267
if (i > 0 && choice <= CONF_CARD)
268
choice = CONF_SCREEN;
274
if (i > 0 && choice <= CONF_SCREEN)
275
choice = CONF_LAYOUT;
277
choice = CONF_SCREEN;
281
if (i > 0 && choice <= CONF_LAYOUT)
282
choice = CONF_FINISH;
284
choice = CONF_LAYOUT;
287
if (WriteXF86Config() < 0)
304
WriteXF86Config(void)
310
xf86config = DialogInput("Write "__XCONFIGFILE__, "Write configuration to file:",
311
10, 60, XF86Config_path ? XF86Config_path :
313
"/etc/X11/"__XCONFIGFILE__, " Ok ", " Cancel ", 0);
315
XF86CONFIGDIR"/"__XCONFIGFILE__, " Ok ", " Cancel ", 0);
318
if (xf86config == NULL)
322
if (XF86Config->conf_modules == NULL) {
323
static char *modules[] = {"extmod", "glx", "dri", "dbe",
324
"record", "xtrap", "type1", "speedo"};
328
XF86Config->conf_modules = (XF86ConfModulePtr)
329
XtCalloc(1, sizeof(XF86ConfModuleRec));
331
XF86Config->conf_modules->mod_comment =
332
XtNewString("\tLoad \"freetype\"\n"
333
"\t# Load \"xtt\"\n");
335
for (i = 0; i < sizeof(modules) / sizeof(modules[0]); i++) {
336
load = (XF86LoadPtr)XtCalloc(1, sizeof(XF86LoadRec));
337
load->load_name = XtNewString(modules[i]);
338
XF86Config->conf_modules->mod_load_lst =
339
xf86addModule(XF86Config->conf_modules->mod_load_lst, load);
344
if (!xf86writeConfigFile(xf86config, XF86Config)) {
347
XmuSnprintf(msg, sizeof(msg), "Failed to write configuration file %s.",
351
(void)Dialog("Write failed!", msg, 8, 60, " Ok ", NULL, 0);
360
static char *protocols[] = {
370
#ifdef WSCONS_SUPPORT
401
int i, nlist, def, proto, emul;
402
char **list = NULL, *device, *str;
403
XF86ConfInputPtr *inputs = NULL;
404
XF86ConfInputPtr input = XF86Config->conf_input_lst;
405
XF86OptionPtr option;
409
if (strcmp(input->inp_driver, "mouse") == 0) {
410
list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
411
list[nlist] = XtMalloc(sizeof(Edit) +
412
strlen(input->inp_identifier) + 1);
413
sprintf(list[nlist], "%s%s", Edit, input->inp_identifier);
414
inputs = (XF86ConfInputPtr*)XtRealloc((XtPointer)inputs, (nlist + 1) *
415
sizeof(XF86ConfInputPtr));
416
inputs[nlist] = input;
419
input = (XF86ConfInputPtr)(input->list.next);
425
list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
426
list[nlist++] = XtNewString("Add new mouse");
428
i = strlen("Remove ") + strlen(inputs[0]->inp_identifier) + 1;
429
list[nlist] = XtMalloc(i);
430
XmuSnprintf(list[nlist], i, "Remove %s", inputs[0]->inp_identifier);
434
list[nlist++] = XtNewString("Remove mouse");
437
i = DialogMenu("Mouse configuration",
438
"You can edit or remove a previously configured mouse, "
439
"or add a new one.", 14, 60, 4, nlist, list,
440
" Ok ", " Cancel ", 0);
442
for (i = 0; i < nlist; i++)
444
XtFree((XtPointer)list);
445
XtFree((XtPointer)inputs);
448
if (nlist > 2 && i == nlist - 1) {
450
for (i = 0; i < nlist - 2; i++) {
451
/* XXX Remove the "Edit " from list entries */
452
memmove(list[i], list[i] + sizeof(Edit) - 1,
453
strlen(list[i]) - sizeof(Edit) + 2);
457
i = DialogMenu("Remove mouse",
458
"Select which mouse to remove",
459
13, 60, 4, nlist - 2, list,
460
" Remove ", " Cancel ", 0);
462
for (i = 0; i < nlist; i++)
464
XtFree((XtPointer)list);
465
XtFree((XtPointer)inputs);
472
for (i = 0; i < nlist; i++)
474
XtFree((XtPointer)list);
475
XtFree((XtPointer)inputs);
476
xf86removeInput(XF86Config, input);
482
for (i = 0; i < nlist; i++)
484
XtFree((XtPointer)list);
485
XtFree((XtPointer)inputs);
490
input = (XF86ConfInputPtr)XtCalloc(1, sizeof(XF86ConfInputRec));
491
XmuSnprintf(label, sizeof(label), "Mouse%d", nlist ? nlist - 2 : 0);
494
input->inp_identifier =
495
DialogInput("Mouse identifier",
496
"Enter an identifier for your mouse definition:",
498
" Next >>", " Cancel ", 0);
499
if (input->inp_identifier == NULL) {
500
XtFree((XtPointer)input);
506
option = xf86findOption(input->inp_option_lst, "Protocol");
508
for (i = 0; i < sizeof(protocols)/sizeof(protocols[0]); i++)
509
if (strcasecmp(option->opt_val, protocols[i]) == 0) {
516
i = DialogMenu("Select mouse protocol",
517
"If you have a serial mouse, it probably will work with "
518
"the \"Auto\" protocol. But, if it is an old serial "
519
"mouse probably it is not PNP; in that case, most serial "
520
"mouses understand the \"Microsoft\" protocol.",
521
19, 60, 7, sizeof(protocols) /
522
sizeof(protocols[0]), protocols, " Next >>", " Cancel ", def);
524
if (input->inp_driver == NULL) {
525
XtFree(input->inp_driver);
526
XtFree((XtPointer)input);
533
if (input->inp_driver) {
534
option = xf86findOption(input->inp_option_lst, "Emulate3Buttons");
535
def = option ? 0 : 1;
539
i = Dialog("Mouse 3 buttons emulation",
540
"If your mouse has only two buttons, it is recommended that "
541
"you enable Emulate3Buttons.\n"
543
"Do you want to enable Emulate3Buttons?",
544
10, 60, " Yes ", " No ", def);
550
option = xf86findOption(input->inp_option_lst, "Device");
552
str = option->opt_val;
554
#ifdef WSCONS_SUPPORT
555
str = "/dev/wsmouse";
556
#elif defined(__FreeBSD__)
557
str = "/dev/sysmouse";
558
#elif defined(__UNIXOS2__)
566
device = DialogInput("Select mouse device",
567
"Enter mouse device:", 10, 40, str,
568
" Finish ", " Cancel ", 0);
569
if (device == NULL) {
570
if (input->inp_driver == NULL) {
571
XtFree(input->inp_driver);
572
XtFree((XtPointer)input);
577
/* Finish mouse configuration */
578
option = xf86findOption(input->inp_option_lst, "Protocol");
580
XtFree((XtPointer)option->opt_val);
581
option->opt_val = XtNewString(protocols[proto]);
584
input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
585
XtNewString("Protocol"), XtNewString(protocols[proto]));
587
option = xf86findOption(input->inp_option_lst, "Emulate3Buttons");
588
if (option && !emul) {
589
xf86removeOption(&input->inp_option_lst, "Emulate3Buttons");
591
else if (option == NULL && emul)
592
input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
593
XtNewString("Emulate3Buttons"), NULL);
595
option = xf86findOption(input->inp_option_lst, "Device");
597
XtFree((XtPointer)option->opt_val);
598
option->opt_val = device;
601
input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
602
XtNewString("Device"), device);
604
if (input->inp_driver == NULL) {
605
input->inp_driver = XtNewString("mouse");
606
XF86Config->conf_input_lst =
607
xf86addInput(XF86Config->conf_input_lst, input);
618
static int first = 1;
619
static XkbRF_RulesPtr rules;
620
static char **models, **layouts;
621
XF86ConfInputPtr *inputs = NULL, input = XF86Config->conf_input_lst;
622
char **list = NULL, *model, *layout;
624
XF86OptionPtr option;
628
if (IS_KBDDRIV(input->inp_driver)) {
629
list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
630
list[nlist] = XtMalloc(sizeof(Edit) +
631
strlen(input->inp_identifier) + 1);
632
sprintf(list[nlist], "%s%s", Edit, input->inp_identifier);
633
inputs = (XF86ConfInputPtr*)XtRealloc((XtPointer)inputs, (nlist + 1) *
634
sizeof(XF86ConfInputPtr));
635
inputs[nlist] = input;
638
input = (XF86ConfInputPtr)(input->list.next);
644
list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
645
list[nlist++] = XtNewString("Add new keyboard");
647
i = strlen("Remove ") + strlen(inputs[0]->inp_identifier) + 1;
648
list[nlist] = XtMalloc(i);
649
XmuSnprintf(list[nlist], i, "Remove %s", inputs[0]->inp_identifier);
653
list[nlist++] = XtNewString("Remove keyboard");
656
i = DialogMenu("Keyboard configuration",
657
"You can edit or remove a previously configured "
658
"keyboard, or add a new one.", 14, 60, 4, nlist, list,
659
" Ok ", " Cancel ", 0);
661
for (i = 0; i < nlist; i++)
663
XtFree((XtPointer)list);
664
XtFree((XtPointer)inputs);
667
if (nlist > 2 && i == nlist - 1) {
669
for (i = 0; i < nlist - 2; i++) {
670
/* XXX Remove the "Edit " from list entries */
671
memmove(list[i], list[i] + sizeof(Edit) - 1,
672
strlen(list[i]) - sizeof(Edit) + 2);
676
i = DialogMenu("Remove keyboard",
677
"Select which keyboard to remove",
678
13, 60, 4, nlist - 2, list,
679
" Remove ", " Cancel ", 0);
681
for (i = 0; i < nlist; i++)
683
XtFree((XtPointer)list);
684
XtFree((XtPointer)inputs);
691
for (i = 0; i < nlist; i++)
693
XtFree((XtPointer)list);
694
XtFree((XtPointer)inputs);
695
xf86removeInput(XF86Config, input);
701
for (i = 0; i < nlist; i++)
703
XtFree((XtPointer)list);
704
XtFree((XtPointer)inputs);
709
input = (XF86ConfInputPtr)XtCalloc(1, sizeof(XF86ConfInputRec));
710
XmuSnprintf(label, sizeof(label), "Keyboard%d", nlist ? nlist - 2 : 0);
713
input->inp_identifier =
714
DialogInput("Keyboard identifier",
715
"Enter an identifier for your keyboard definition:",
717
" Next >>", " Cancel ", 0);
718
if (input->inp_identifier == NULL) {
719
XtFree((XtPointer)input);
727
rulesfile = XKB_RULES_DIR "/xfree98";
729
rulesfile = XKB_RULES_DIR "/"__XKBDEFRULES__;
731
rules = XkbRF_Load(rulesfile, "", True, False);
735
Dialog("Configuration error",
736
"XKB rules file not found.\n"
738
"Keyboard XKB options will be set to default values.",
739
10, 50, " Ok ", NULL, 0);
740
if (input->inp_driver == NULL) {
741
input->inp_option_lst =
742
xf86addNewOption(input->inp_option_lst,
743
XtNewString("XkbModel"), XtNewString("pc101"));
744
input->inp_option_lst =
745
xf86addNewOption(input->inp_option_lst,
746
XtNewString("XkbLayout"), XtNewString("us"));
747
#if defined(USE_DEPRECATED_KEYBOARD_DRIVER)
748
input->inp_driver = XtNewString("keyboard");
750
input->inp_driver = XtNewString("kbd");
752
XF86Config->conf_input_lst =
753
xf86addInput(XF86Config, input);
757
models = (char**)XtMalloc(sizeof(char*) * rules->models.num_desc);
758
for (i = 0; i < rules->models.num_desc; i++)
759
models[i] = XtNewString(rules->models.desc[i].desc);
760
layouts = (char**)XtMalloc(sizeof(char*) * rules->layouts.num_desc);
761
for (i = 0; i < rules->layouts.num_desc; i++)
762
layouts[i] = XtNewString(rules->layouts.desc[i].desc);
764
else if (rules == NULL)
768
option = xf86findOption(input->inp_option_lst, "XkbModel");
770
for (i = 0; i < rules->models.num_desc; i++)
771
if (strcasecmp(option->opt_val, rules->models.desc[i].name) == 0) {
778
i = DialogMenu("Keyboard model",
779
"Please select one of the following keyboard types that is "
780
"the better description of your keyboard. If nothing really "
781
"matches, choose \"Generic 101-key PC\".\n",
782
20, 60, 9, rules->models.num_desc,
783
models, " Next >>", " Cancel ", def);
786
model = rules->models.desc[i].name;
789
option = xf86findOption(input->inp_option_lst, "XkbLayout");
791
for (i = 0; i < rules->layouts.num_desc; i++)
792
if (strcasecmp(option->opt_val, rules->layouts.desc[i].name) == 0) {
799
i = DialogMenu("Keyboard layout",
800
"Select keyboard layout:",
801
20, 60, 11, rules->layouts.num_desc,
802
layouts, " Finish ", " Cancel ", def);
805
layout = rules->layouts.desc[i].name;
807
/* Finish keyboard configuration */
808
option = xf86findOption(input->inp_option_lst, "XkbModel");
810
XtFree((XtPointer)option->opt_val);
811
option->opt_val = XtNewString(model);
814
input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
815
XtNewString("XkbModel"), XtNewString(model));
817
option = xf86findOption(input->inp_option_lst, "XkbLayout");
819
XtFree((XtPointer)option->opt_val);
820
option->opt_val = XtNewString(layout);
823
input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
824
XtNewString("XkbLayout"), XtNewString(layout));
826
if (input->inp_driver == NULL) {
827
#if defined(USE_DEPRECATED_KEYBOARD_DRIVER)
828
input->inp_driver = XtNewString("keyboard");
830
input->inp_driver = XtNewString("kbd");
832
XF86Config->conf_input_lst =
833
xf86addInput(XF86Config->conf_input_lst, input);
839
static char *hsync[] = {
840
#define CONF_MONITOR_HSYNC 0
841
"Enter your own horizontal sync range",
842
"31.5; Standard VGA, 640x480 @ 60 Hz",
843
"31.5 - 35.1; Super VGA, 800x600 @ 56 Hz",
844
"31.5, 35.5; 8514 Compatible, 1024x768 @ 87 Hz interlaced (no 800x600)",
845
"31.5, 35.15, 35.5; Super VGA, 1024x768 @ 87 Hz int., 800x600 @ 56 Hz",
846
"31.5 - 37.9; Extended Super VGA, 800x600 @ 60 Hz, 640x480 @ 72 Hz",
847
"31.5 - 48.5; Non-Interlaced SVGA, 1024x768 @ 60 Hz, 800x600 @ 72 Hz",
848
"31.5 - 57.0; High Frequency SVGA, 1024x768 @ 70 Hz",
849
"31.5 - 64.3; Monitor that can do 1280x1024 @ 60 Hz",
850
"31.5 - 79.0; Monitor that can do 1280x1024 @ 74 Hz",
851
"31.5 - 82.0; Monitor that can do 1280x1024 @ 76 Hz",
852
"31.5 - 92.0; Monitor that can do 1280x1024 @ 85 Hz",
853
"31.5 - 108.0; Monitor that can do 1600x1200 @ 85 Hz",
854
"31.5 - 128.5; Monitor that can do 1920x1440 @ 85 Hz",
855
"31.5 - 137.0; Monitor that can do 2048x1536 @ 85 Hz"
858
static char *vrefresh[] = {
859
#define CONF_MONITOR_VREFRESH 0
860
"Enter your own vertical sync range",
871
XF86ConfMonitorPtr *monitors = NULL, monitor = XF86Config->conf_monitor_lst;
872
char **list = NULL, *identifier = NULL, *tmp;
874
char hsync_str[256], vrefresh_str[256];
876
hsync_str[0] = vrefresh_str[0] = '\0';
879
list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
880
list[nlist] = XtMalloc(sizeof(Edit) +
881
strlen(monitor->mon_identifier) + 1);
882
sprintf(list[nlist], "%s%s", Edit, monitor->mon_identifier);
883
monitors = (XF86ConfMonitorPtr*)XtRealloc((XtPointer)monitors, (nlist + 1) *
884
sizeof(XF86ConfMonitorPtr));
885
monitors[nlist] = monitor;
887
monitor = (XF86ConfMonitorPtr)(monitor->list.next);
893
list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
894
list[nlist++] = XtNewString("Add new monitor");
896
i = strlen("Remove ") + strlen(monitors[0]->mon_identifier) + 1;
897
list[nlist] = XtMalloc(i);
898
XmuSnprintf(list[nlist], i, "Remove %s", monitors[0]->mon_identifier);
902
list[nlist++] = XtNewString("Remove monitor");
905
i = DialogMenu("Monitor configuration",
906
"You can edit or remove a previously configured "
907
"monitor, or add a new one.", 14, 60, 4, nlist, list,
908
" Ok ", " Cancel ", 0);
910
for (i = 0; i < nlist; i++)
912
XtFree((XtPointer)list);
913
XtFree((XtPointer)monitors);
916
if (nlist > 2 && i == nlist - 1) {
918
for (i = 0; i < nlist - 2; i++) {
919
/* XXX Remove the "Edit " from list entries */
920
memmove(list[i], list[i] + sizeof(Edit) - 1,
921
strlen(list[i]) - sizeof(Edit) + 2);
925
i = DialogMenu("Remove monitor",
926
"Select which monitor to remove",
927
13, 60, 4, nlist - 2, list,
928
" Remove ", " Cancel ", 0);
930
for (i = 0; i < nlist; i++)
932
XtFree((XtPointer)list);
933
XtFree((XtPointer)monitors);
936
monitor = monitors[i];
939
monitor = monitors[0];
940
for (i = 0; i < nlist; i++)
942
XtFree((XtPointer)list);
943
XtFree((XtPointer)monitors);
944
xf86removeMonitor(XF86Config, monitor);
948
monitor = monitors[i];
950
for (i = 0; i < nlist; i++)
952
XtFree((XtPointer)list);
953
XtFree((XtPointer)monitors);
955
if (monitor == NULL) {
958
monitor = (XF86ConfMonitorPtr)XtCalloc(1, sizeof(XF86ConfMonitorRec));
959
XmuSnprintf(label, sizeof(label), "Monitor%d", nlist ? nlist - 2 : 0);
963
DialogInput("Monitor identifier",
964
"Enter an identifier for your monitor definition:",
966
" Next >>", " Cancel ", 0);
967
if (identifier == NULL) {
968
XtFree((XtPointer)monitor);
973
if (monitor->mon_identifier == NULL) {
976
i = Dialog("Monitor configuration",
977
"Now we want to set the specifications of the monitor. The "
978
"two critical parameters are the vertical refresh rate, which "
979
"is the rate at which the whole screen is refreshed, and most "
980
"importantly the horizontal sync rate, which is the rate at "
981
"which scanlines are displayed.\n"
983
"The valid range for horizontal sync and vertical sync should "
984
"be documented in the manual of your monitor.",
985
15, 60, " Next >>", " Cancel ", 0);
988
XtFree((XtPointer)monitor);
994
if (monitor->mon_identifier) {
997
parser_range_to_string(hsync_str, &(monitor->mon_hsync[0]),
998
monitor->mon_n_hsync);
999
len = strlen(hsync_str);
1000
for (i = 1; i < sizeof(hsync) / sizeof(hsync[0]); i++) {
1001
tmp = strchr(hsync[i], ';');
1002
if (strncmp(hsync_str, hsync[i], len) == 0) {
1008
if (hsync_str[0] == '\0')
1009
strcpy(hsync_str, "31.5");
1013
i = DialogMenu("Monitor HorizSync",
1014
"You must indicate the horizontal sync range of your "
1015
"monitor. You can either select one of the predefined "
1016
"ranges below that correspond to industry-standard monitor "
1017
"types, or give a specific range.",
1018
22, 78, 11, sizeof(hsync) /
1019
sizeof(hsync[0]), hsync, " Next >>", " Cancel ", def);
1021
if (monitor->mon_identifier == NULL) {
1023
XtFree((XtPointer)monitor);
1027
if (i == CONF_MONITOR_HSYNC) {
1030
tmp = DialogInput("Monitor HorizSync",
1031
"Please enter the horizontal sync range of your "
1032
"monitor, in the format used in the table of monitor "
1033
"types above. You can either specify one or more "
1034
"continuous ranges (e.g. 15-25, 30-50), or one or more "
1035
"fixed sync frequencies.\n"
1037
"Horizontal sync range:", 16, 62, hsync_str,
1038
" Ok ", " Cancel ", def);
1040
if (monitor->mon_identifier == NULL) {
1042
XtFree((XtPointer)monitor);
1046
XmuSnprintf(hsync_str, sizeof(hsync_str), "%s", tmp);
1050
tmp = strchr(hsync[i], ';');
1051
strncpy(hsync_str, hsync[i], tmp - hsync[i]);
1052
hsync_str[tmp - hsync[i]] = '\0';
1056
if (monitor->mon_identifier) {
1057
parser_range_to_string(vrefresh_str, &(monitor->mon_vrefresh[0]),
1058
monitor->mon_n_vrefresh);
1059
for (i = 1; i < sizeof(vrefresh) / sizeof(vrefresh[0]); i++) {
1060
if (strcmp(vrefresh_str, vrefresh[i]) == 0) {
1066
if (vrefresh_str[0] == '\0')
1067
strcpy(vrefresh_str, "50 - 70");
1070
i = DialogMenu("Monitor VertRefresh",
1071
"You must indicate the vertical sync range of your monitor. "
1072
"You can either select one of the predefined ranges below "
1073
"that correspond to industry-standard monitor types, or "
1074
"give a specific range. For interlaced modes, the number "
1075
"that counts is the high one (e.g. 87 Hz rather than 43 Hz).",
1076
19, 60, 5, sizeof(vrefresh) /
1077
sizeof(vrefresh[0]), vrefresh, " Finish ", " Cancel ", def);
1079
if (monitor->mon_identifier == NULL) {
1081
XtFree((XtPointer)monitor);
1085
if (i == CONF_MONITOR_VREFRESH) {
1088
tmp = DialogInput("Monitor VertRefresh",
1089
"Vertical sync range:", 10, 50, vrefresh_str,
1090
" Done ", " Cancel ", 0);
1092
if (monitor->mon_identifier == NULL) {
1094
XtFree((XtPointer)monitor);
1098
XmuSnprintf(vrefresh_str, sizeof(vrefresh_str), "%s", tmp);
1102
strcpy(vrefresh_str, vrefresh[i]);
1104
/* Finish monitor configuration */
1105
monitor->mon_n_hsync = string_to_parser_range(hsync_str,
1106
&(monitor->mon_hsync[0]), CONF_MAX_HSYNC);
1107
monitor->mon_n_vrefresh = string_to_parser_range(vrefresh_str,
1108
&(monitor->mon_vrefresh[0]), CONF_MAX_VREFRESH);
1109
if (monitor->mon_identifier == NULL) {
1110
monitor->mon_identifier = identifier;
1111
XF86Config->conf_monitor_lst =
1112
xf86addMonitor(XF86Config->conf_monitor_lst, monitor);
1122
XF86ConfDevicePtr *devices = NULL, device = XF86Config->conf_device_lst;
1123
char **list = NULL, *identifier = NULL, *driver, *busid, *tmp;
1125
CardsEntry *entry = NULL;
1126
static char **drivers;
1127
static int ndrivers;
1128
static char *xdrivers[] = {
1163
xf86cfgModuleOptions *opts = module_options;
1168
if (opts->type == VideoModule) {
1170
drivers = (char**)XtRealloc((XtPointer)drivers,
1171
ndrivers * sizeof(char*));
1172
/* XXX no private copy */
1173
drivers[ndrivers - 1] = opts->name;
1181
ndrivers = sizeof(xdrivers) / sizeof(xdrivers[0]);
1187
list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
1188
list[nlist] = XtMalloc(sizeof(Edit) +
1189
strlen(device->dev_identifier) + 1);
1190
sprintf(list[nlist], "%s%s", Edit, device->dev_identifier);
1191
devices = (XF86ConfDevicePtr*)XtRealloc((XtPointer)devices, (nlist + 1) *
1192
sizeof(XF86ConfDevicePtr));
1193
devices[nlist] = device;
1195
device = (XF86ConfDevicePtr)(device->list.next);
1201
list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
1202
list[nlist++] = XtNewString("Add new card");
1204
i = strlen("Remove ") + strlen(devices[0]->dev_identifier) + 1;
1205
list[nlist] = XtMalloc(i);
1206
XmuSnprintf(list[nlist], i, "Remove %s", devices[0]->dev_identifier);
1210
list[nlist++] = XtNewString("Remove device");
1213
i = DialogMenu("Card configuration",
1214
"You can edit or remove a previously configured "
1215
"card, or add a new one.", 14, 60, 4, nlist, list,
1216
" Ok ", " Cancel ", 0);
1218
for (i = 0; i < nlist; i++)
1220
XtFree((XtPointer)list);
1221
XtFree((XtPointer)devices);
1224
if (nlist > 2 && i == nlist - 1) {
1226
for (i = 0; i < nlist - 2; i++) {
1227
/* XXX Remove the "Edit " from list entries */
1228
memmove(list[i], list[i] + sizeof(Edit) - 1,
1229
strlen(list[i]) - sizeof(Edit) + 2);
1233
i = DialogMenu("Remove card",
1234
"Select which card to remove",
1235
13, 60, 4, nlist - 2, list,
1236
" Remove ", " Cancel ", 0);
1238
for (i = 0; i < nlist; i++)
1240
XtFree((XtPointer)list);
1241
XtFree((XtPointer)devices);
1244
device = devices[i];
1247
device = devices[0];
1248
for (i = 0; i < nlist; i++)
1250
XtFree((XtPointer)list);
1251
XtFree((XtPointer)devices);
1252
xf86removeDevice(XF86Config, device);
1256
device = devices[i];
1258
for (i = 0; i < nlist; i++)
1260
XtFree((XtPointer)list);
1261
XtFree((XtPointer)devices);
1263
if (device == NULL) {
1266
device = (XF86ConfDevicePtr)XtCalloc(1, sizeof(XF86ConfDeviceRec));
1267
device->dev_chipid = device->dev_chiprev = device->dev_irq = -1;
1268
XmuSnprintf(label, sizeof(label), "Card%d", nlist ? nlist - 2 : 0);
1272
DialogInput("Card identifier",
1273
"Enter an identifier for your card definition:",
1275
" Next >>", " Cancel ", 0);
1276
if (identifier == NULL) {
1277
XtFree((XtPointer)device);
1284
if (Dialog("Card configuration",
1285
"Now we must configure video card specific settings. At this "
1286
"point you can choose to make a selection out of a database of "
1287
"video card definitions.\n"
1289
"The database entries include information about the chipset, "
1290
"what driver to run, the Ramdac and ClockChip, and comments "
1291
"that will be included in the Device section. However, a lot "
1292
"of definitions only hint about what driver to run (based on "
1293
"the chipset the card uses) and are untested.\n"
1295
"Do you want to look at the card database?",
1296
18, 60, " Yes ", " No ", device->dev_identifier != NULL) == 0) {
1297
static char **cards;
1300
if (cards == NULL) {
1301
ReadCardsDatabase();
1302
cards = GetCardNames(&ncards);
1303
cards = (char**)XtRealloc((XtPointer)cards,
1304
(ncards + 1) * sizeof(char*));
1305
for (i = ncards; i > 0; i--)
1306
cards[i] = cards[i - 1];
1307
cards[0] = "** Unlisted card **";
1310
if (device->dev_card)
1311
entry = LookupCard(device->dev_card);
1314
for (i = 0; i < NumCardsEntry; i++)
1315
if (strcasecmp(CardsDB[i]->name, entry->name) == 0) {
1319
/* make sure entry is set to null again */
1323
i = DialogMenu("Card database",
1324
"Select name that better matches your card:",
1325
20, 70, 11, ncards, cards, "Next >>", " Cancel ", def);
1327
entry = LookupCard(cards[i]);
1331
tmp = device->dev_driver ? device->dev_driver : entry && entry->driver ?
1332
entry->driver : "vga";
1333
for (i = 0; i < ndrivers; i++)
1334
if (strcmp(drivers[i], tmp) == 0) {
1341
i = DialogMenu("Card driver",
1342
"You can select the driver for your card here, or just press "
1343
"Enter to use the default/current:", 20, 50, 9,
1344
ndrivers, drivers, " Ok ", " Cancel ", def);
1346
if (device->dev_identifier == NULL) {
1348
XtFree((XtPointer)device);
1352
driver = ndrivers ? drivers[i] : "vga";
1356
tmp = device->dev_busid ? device->dev_busid : "";
1357
busid = DialogInput("Card BusID",
1358
"You normally does not need to fill this field "
1359
"if you have only one video card:", 11, 50, tmp,
1360
" Finish ", " Cancel ", 0);
1362
/* Finish card configuration */
1364
XtFree(device->dev_card);
1365
device->dev_card = XtNewString(entry->name);
1366
if (entry->chipset) {
1367
XtFree(device->dev_chipset);
1368
device->dev_chipset = XtNewString(entry->chipset);
1370
if (entry->ramdac) {
1371
XtFree(device->dev_ramdac);
1372
device->dev_ramdac = XtNewString(entry->ramdac);
1374
if (entry->clockchip) {
1375
XtFree(entry->clockchip);
1376
device->dev_clockchip = XtNewString(entry->clockchip);
1380
XtFree(device->dev_busid);
1382
device->dev_busid = busid;
1384
device->dev_busid = NULL;
1388
XtFree(device->dev_driver);
1389
device->dev_driver = XtNewString(driver);
1390
if (device->dev_identifier == NULL) {
1391
device->dev_identifier = identifier;
1392
XF86Config->conf_device_lst =
1393
xf86addDevice(XF86Config->conf_device_lst, device);
1399
static char *depths[] = {
1400
"1 bit, monochrome",
1402
"8 bit, 256 colors",
1403
"15 bits, 32Kb colors",
1404
"16 bits, 65Kb colors",
1405
"24 bits, 16Mb colors",
1408
static char *modes[] = {
1430
int i, disp_allocated;
1431
XF86ConfScreenPtr *screens = NULL, screen = XF86Config->conf_screen_lst;
1432
char **list = NULL, *identifier = NULL;
1434
XF86ConfDevicePtr device = NULL;
1435
XF86ConfMonitorPtr monitor = NULL;
1436
XF86ConfDisplayPtr display;
1437
XF86ModePtr mode, ptr = NULL;
1442
list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
1443
list[nlist] = XtMalloc(sizeof(Edit) +
1444
strlen(screen->scrn_identifier) + 1);
1445
sprintf(list[nlist], "%s%s", Edit, screen->scrn_identifier);
1446
screens = (XF86ConfScreenPtr*)XtRealloc((XtPointer)screens, (nlist + 1) *
1447
sizeof(XF86ConfScreenPtr));
1448
screens[nlist] = screen;
1450
screen = (XF86ConfScreenPtr)(screen->list.next);
1456
list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
1457
list[nlist++] = XtNewString("Add new screen");
1459
i = strlen("Remove ") + strlen(screens[0]->scrn_identifier) + 1;
1460
list[nlist] = XtMalloc(i);
1461
XmuSnprintf(list[nlist], i, "Remove %s", screens[0]->scrn_identifier);
1465
list[nlist++] = XtNewString("Remove screen");
1468
i = DialogMenu("Screen configuration",
1469
"You can edit or remove a previously configured "
1470
"screen, or add a new one.", 14, 60, 4, nlist, list,
1471
" Ok ", " Cancel ", 0);
1473
for (i = 0; i < nlist; i++)
1475
XtFree((XtPointer)list);
1476
XtFree((XtPointer)screens);
1479
if (nlist > 2 && i == nlist - 1) {
1481
for (i = 0; i < nlist - 2; i++) {
1482
/* XXX Remove the "Edit " from list entries */
1483
memmove(list[i], list[i] + sizeof(Edit) - 1,
1484
strlen(list[i]) - sizeof(Edit) + 2);
1488
i = DialogMenu("Remove screen",
1489
"Select which screen to remove",
1490
13, 60, 4, nlist - 2, list,
1491
" Remove ", " Cancel ", 0);
1493
for (i = 0; i < nlist; i++)
1495
XtFree((XtPointer)list);
1496
XtFree((XtPointer)screens);
1499
screen = screens[i];
1502
screen = screens[0];
1503
for (i = 0; i < nlist; i++)
1505
XtFree((XtPointer)list);
1506
XtFree((XtPointer)screens);
1507
xf86removeScreen(XF86Config, screen);
1511
screen = screens[i];
1513
for (i = 0; i < nlist; i++)
1515
XtFree((XtPointer)list);
1516
XtFree((XtPointer)screens);
1518
if (screen == NULL) {
1520
XF86ConfDevicePtr *devices = NULL;
1521
XF86ConfMonitorPtr *monitors = NULL;
1523
device = XF86Config->conf_device_lst;
1524
monitor = XF86Config->conf_monitor_lst;
1526
if (device == NULL || monitor == NULL) {
1529
Dialog("Configuration error",
1530
"You need to configure (at least) one card and one "
1531
"monitor before creating a screen definition.",
1532
9, 50, " Ok ", NULL, 0);
1537
XmuSnprintf(label, sizeof(label), "Screen%d", nlist ? nlist - 2 : 0);
1541
DialogInput("Screen identifier",
1542
"Enter an identifier for your screen definition:",
1544
" Next >>", " Cancel ", 0);
1545
if (identifier == NULL)
1551
list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
1552
list[nlist] = XtNewString(device->dev_identifier);
1553
devices = (XF86ConfDevicePtr*)XtRealloc((XtPointer)devices, (nlist + 1) *
1554
sizeof(XF86ConfDevicePtr));
1555
devices[nlist] = device;
1557
device = (XF86ConfDevicePtr)(device->list.next);
1561
i = DialogMenu("Screen card", "Please select a video card:",
1562
13, 60, 4, nlist, list, " Next >>", " Cancel ", 0);
1563
for (def = 0; def < nlist; def++)
1565
XtFree((XtPointer)list);
1568
XtFree((XtPointer)devices);
1571
device = devices[i];
1572
XtFree((XtPointer)devices);
1577
list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
1578
list[nlist] = XtNewString(monitor->mon_identifier);
1579
monitors = (XF86ConfMonitorPtr*)XtRealloc((XtPointer)monitors, (nlist + 1) *
1580
sizeof(XF86ConfMonitorPtr));
1581
monitors[nlist] = monitor;
1583
monitor = (XF86ConfMonitorPtr)(monitor->list.next);
1585
XmuSnprintf(label, sizeof(label),
1586
"Select the monitor connected to \"%s\":",
1587
device->dev_identifier);
1590
i = DialogMenu("Screen monitor", label,
1591
13, 60, 4, nlist, list, " Next >>", " Cancel ", 0);
1592
for (def = 0; def < nlist; def++)
1594
XtFree((XtPointer)list);
1597
XtFree((XtPointer)monitors);
1600
monitor = monitors[i];
1601
XtFree((XtPointer)monitors);
1603
screen = (XF86ConfScreenPtr)XtCalloc(1, sizeof(XF86ConfScreenRec));
1604
screen->scrn_device = device;
1605
screen->scrn_monitor = monitor;
1608
if (screen->scrn_defaultdepth == 1)
1610
else if (screen->scrn_defaultdepth == 4)
1612
else if (screen->scrn_defaultdepth == 8)
1614
else if (screen->scrn_defaultdepth == 15)
1616
else if (screen->scrn_defaultdepth == 16)
1618
else if (screen->scrn_defaultdepth == 24)
1621
if (screen->scrn_device && screen->scrn_device->dev_driver &&
1622
strcmp(screen->scrn_device->dev_driver, "vga") == 0)
1629
i = DialogMenu("Screen depth",
1630
"Please specify which color depth you want to use by default:",
1631
15, 60, 6, sizeof(depths) / sizeof(depths[0]), depths,
1632
" Next >>", " Cancel ", def);
1634
if (screen->scrn_identifier == NULL) {
1636
XtFree((XtPointer)screen);
1641
/* XXX depths must begin with the depth number */
1642
screen->scrn_defaultdepth = atoi(depths[i]);
1644
def = 0; /* use def to count how many modes are selected*/
1647
checks = XtMalloc(sizeof(modes) / sizeof(modes[0]));
1648
/* XXX list fields in the code below are not allocated */
1650
display = screen->scrn_display_lst;
1651
while (display && display->disp_depth != screen->scrn_defaultdepth)
1652
display = (XF86ConfDisplayPtr)(display->list.next);
1653
if (display == NULL) {
1654
display = (XF86ConfDisplayPtr)XtCalloc(1, sizeof(XF86ConfDisplayRec));
1655
display->disp_white.red = display->disp_black.red = -1;
1656
display->disp_depth = screen->scrn_defaultdepth;
1660
mode = display->disp_mode_lst;
1662
for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++)
1663
if (strcmp(modes[i], mode->mode_name) == 0) {
1667
if (i == sizeof(modes) / sizeof(modes[0])) {
1668
list = (char**)XtRealloc((XtPointer)list,
1669
(nlist + 1) * sizeof(char*));
1670
list[nlist] = mode->mode_name;
1671
checks = XtRealloc(checks, sizeof(modes) / sizeof(modes[0]) +
1678
mode = (XF86ModePtr)(mode->list.next);
1682
for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++)
1683
checks[i + nlist] = 0;
1685
mode = display->disp_mode_lst;
1687
for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++)
1688
if (strcmp(modes[i], mode->mode_name) == 0) {
1690
checks[i + nlist] = 1;
1693
mode = (XF86ModePtr)(mode->list.next);
1696
if (nlist == 0 && def == 0)
1697
checks[7] = 1; /* 640x480 */
1698
list = (char**)XtRealloc((XtPointer)list, (nlist + sizeof(modes) /
1699
sizeof(modes[0])) * sizeof(char*));
1700
for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++)
1701
list[i + nlist] = modes[i];
1702
nlist += sizeof(modes) / sizeof(modes[0]);
1706
i = DialogCheckBox("Screen modes",
1707
"Select the video modes for this screen:",
1708
17, 60, 8, sizeof(modes) / sizeof(modes[0]), modes,
1709
" Finish ", " Cancel ", checks);
1711
if (screen->scrn_identifier == NULL) {
1713
XtFree((XtPointer)screen);
1714
XtFree((XtPointer)list);
1716
XtFree((XtPointer)display);
1721
mode = display->disp_mode_lst;
1723
ptr = (XF86ModePtr)(mode->list.next);
1724
XtFree(mode->mode_name);
1725
XtFree((XtPointer)mode);
1728
display->disp_mode_lst = NULL;
1730
for (i = 0; i < nlist; i++) {
1732
mode = (XF86ModePtr)XtCalloc(1, sizeof(XF86ModeRec));
1733
mode->mode_name = XtNewString(list[i]);
1734
if (display->disp_mode_lst == NULL)
1735
display->disp_mode_lst = ptr = mode;
1737
ptr->list.next = mode;
1742
XtFree((XtPointer)list);
1744
if (disp_allocated) {
1745
display->list.next = NULL;
1746
if (screen->scrn_display_lst == NULL)
1747
screen->scrn_display_lst = display;
1749
screen->scrn_display_lst->list.next = display;
1752
if (screen->scrn_identifier == NULL) {
1753
screen->scrn_identifier = identifier;
1754
screen->scrn_monitor_str = XtNewString(monitor->mon_identifier);
1755
screen->scrn_device_str = XtNewString(device->dev_identifier);
1756
XF86Config->conf_screen_lst =
1757
xf86addScreen(XF86Config->conf_screen_lst, screen);
1763
static XF86ConfAdjacencyPtr
1764
CopyAdjacency(XF86ConfAdjacencyPtr ptr)
1766
XF86ConfAdjacencyPtr adj = (XF86ConfAdjacencyPtr)
1767
XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
1769
adj->adj_scrnum = ptr->adj_scrnum;
1770
adj->adj_screen = ptr->adj_screen;
1771
adj->adj_screen_str = XtNewString(ptr->adj_screen_str);
1772
adj->adj_top = ptr->adj_top;
1773
if (ptr->adj_top_str)
1774
adj->adj_top_str = XtNewString(ptr->adj_top_str);
1775
adj->adj_bottom = ptr->adj_bottom;
1776
if (ptr->adj_bottom_str)
1777
adj->adj_bottom_str = XtNewString(ptr->adj_bottom_str);
1778
adj->adj_left = ptr->adj_left;
1779
if (ptr->adj_left_str)
1780
adj->adj_left_str = XtNewString(ptr->adj_left_str);
1781
adj->adj_right = ptr->adj_right;
1782
if (ptr->adj_right_str)
1783
adj->adj_right_str = XtNewString(ptr->adj_right_str);
1784
adj->adj_where = ptr->adj_where;
1785
adj->adj_x = ptr->adj_x;
1786
adj->adj_y = ptr->adj_y;
1787
if (ptr->adj_refscreen)
1788
adj->adj_refscreen = XtNewString(ptr->adj_refscreen);
1793
static XF86ConfInactivePtr
1794
CopyInactive(XF86ConfInactivePtr ptr)
1796
XF86ConfInactivePtr inac = (XF86ConfInactivePtr)
1797
XtCalloc(1, sizeof(XF86ConfInactiveRec));
1799
inac->inactive_device = ptr->inactive_device;
1800
if (ptr->inactive_device_str)
1801
inac->inactive_device_str = XtNewString(ptr->inactive_device_str);
1806
static XF86ConfInputrefPtr
1807
CopyInputref(XF86ConfInputrefPtr ptr)
1809
XF86ConfInputrefPtr iref = (XF86ConfInputrefPtr)
1810
XtCalloc(1, sizeof(XF86ConfInputrefRec));
1811
XF86OptionPtr opt = ptr->iref_option_lst;
1813
iref->iref_inputdev = ptr->iref_inputdev;
1814
if (ptr->iref_inputdev_str)
1815
iref->iref_inputdev_str = XtNewString(ptr->iref_inputdev_str);
1817
iref->iref_option_lst = xf86addNewOption(iref->iref_option_lst,
1818
XtNewString(opt->opt_name),
1819
opt->opt_val ? XtNewString(opt->opt_val) : NULL);
1820
opt = (XF86OptionPtr)(opt->list.next);
1826
static XF86ConfLayoutPtr
1827
CopyLayout(XF86ConfLayoutPtr ptr)
1829
XF86ConfLayoutPtr lay = (XF86ConfLayoutPtr)
1830
XtCalloc(1, sizeof(XF86ConfLayoutRec));
1831
XF86ConfAdjacencyPtr adj = ptr->lay_adjacency_lst, padj;
1832
XF86ConfInactivePtr inac = ptr->lay_inactive_lst, pinac;
1833
XF86ConfInputrefPtr iref = ptr->lay_input_lst, piref;
1834
XF86OptionPtr opt = ptr->lay_option_lst;
1836
if (ptr->lay_identifier)
1837
lay->lay_identifier = XtNewString(ptr->lay_identifier);
1839
padj = lay->lay_adjacency_lst = CopyAdjacency(adj);
1840
adj = (XF86ConfAdjacencyPtr)(adj->list.next);
1842
padj->list.next = CopyAdjacency(adj);
1843
padj = (XF86ConfAdjacencyPtr)(padj->list.next);
1844
adj = (XF86ConfAdjacencyPtr)(adj->list.next);
1848
pinac = lay->lay_inactive_lst = CopyInactive(inac);
1849
inac = (XF86ConfInactivePtr)(inac->list.next);
1851
pinac->list.next = CopyInactive(inac);
1852
pinac = (XF86ConfInactivePtr)(pinac->list.next);
1853
inac = (XF86ConfInactivePtr)(inac->list.next);
1857
piref = lay->lay_input_lst = CopyInputref(iref);
1858
iref = (XF86ConfInputrefPtr)(iref->list.next);
1860
piref->list.next = CopyInputref(iref);
1861
piref = (XF86ConfInputrefPtr)(piref->list.next);
1862
iref = (XF86ConfInputrefPtr)(iref->list.next);
1867
lay->lay_option_lst = xf86addNewOption(lay->lay_option_lst,
1868
XtNewString(opt->opt_name),
1869
opt->opt_val ? XtNewString(opt->opt_val) : NULL);
1870
opt = (XF86OptionPtr)(opt->list.next);
1877
FreeLayout(XF86ConfLayoutPtr lay)
1879
static XF86ConfigRec xf86config;
1881
xf86config.conf_layout_lst = lay;
1882
xf86removeLayout(&xf86config, lay);
1889
XF86ConfLayoutPtr *layouts = NULL, rlayout = NULL,
1890
layout = XF86Config->conf_layout_lst;
1891
XF86ConfInputPtr input = XF86Config->conf_input_lst;
1892
char **list = NULL, *identifier = NULL;
1893
XF86ConfInputPtr *mouses = NULL, *keyboards = NULL, mouse, keyboard;
1894
XF86ConfInputrefPtr iref, piref, mref, kref;
1895
XF86ConfAdjacencyPtr adj, padj;
1896
int nmouses, nkeyboards;
1898
XF86OptionPtr option;
1899
XF86ConfScreenPtr screen, *screens;
1901
nmouses = nkeyboards = 0;
1903
if (strcmp(input->inp_driver, "mouse") == 0) {
1904
mouses = (XF86ConfInputPtr*)XtRealloc((XtPointer)mouses,
1905
(nmouses + 1) * sizeof(XF86ConfInputPtr));
1906
mouses[nmouses] = input;
1909
else if (IS_KBDDRIV(input->inp_driver)) {
1910
keyboards = (XF86ConfInputPtr*)XtRealloc((XtPointer)keyboards,
1911
(nkeyboards + 1) * sizeof(XF86ConfInputPtr));
1912
keyboards[nkeyboards] = input;
1915
input = (XF86ConfInputPtr)(input->list.next);
1917
if (XF86Config->conf_screen_lst == NULL ||
1918
nmouses == 0 || nkeyboards == 0) {
1919
XtFree((XtPointer)mouses);
1920
XtFree((XtPointer)keyboards);
1923
Dialog("Configuration error",
1924
"You need to configure (at least) one screen, mouse "
1925
"and keyboard before creating a layout definition.",
1926
9, 50, " Ok ", NULL, 0);
1932
list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
1933
list[nlist] = XtMalloc(sizeof(Edit) +
1934
strlen(layout->lay_identifier) + 1);
1935
sprintf(list[nlist], "%s%s", Edit, layout->lay_identifier);
1936
layouts = (XF86ConfLayoutPtr*)XtRealloc((XtPointer)layouts, (nlist + 1) *
1937
sizeof(XF86ConfLayoutPtr));
1938
layouts[nlist] = layout;
1940
layout = (XF86ConfLayoutPtr)(layout->list.next);
1946
list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
1947
list[nlist++] = XtNewString("Add new layout");
1949
i = strlen("Remove ") + strlen(layouts[0]->lay_identifier) + 1;
1950
list[nlist] = XtMalloc(i);
1951
XmuSnprintf(list[nlist], i, "Remove %s", layouts[0]->lay_identifier);
1955
list[nlist++] = XtNewString("Remove layout");
1958
i = DialogMenu("Layout configuration",
1959
"You can edit or remove a previously configured "
1960
"layout, or add a new one.", 14, 60, 4, nlist, list,
1961
" Ok ", " Cancel ", 0);
1963
for (i = 0; i < nlist; i++)
1965
XtFree((XtPointer)list);
1966
XtFree((XtPointer)layouts);
1967
XtFree((XtPointer)mouses);
1968
XtFree((XtPointer)keyboards);
1971
if (nlist > 2 && i == nlist - 1) {
1973
for (i = 0; i < nlist - 2; i++) {
1974
/* XXX Remove the "Edit " from list entries */
1975
memmove(list[i], list[i] + sizeof(Edit) - 1,
1976
strlen(list[i]) - sizeof(Edit) + 2);
1980
i = DialogMenu("Remove layout",
1981
"Select which layout to remove",
1982
13, 60, 4, nlist - 2, list,
1983
" Remove ", " Cancel ", 0);
1985
for (i = 0; i < nlist; i++)
1987
XtFree((XtPointer)list);
1988
XtFree((XtPointer)layouts);
1989
XtFree((XtPointer)mouses);
1990
XtFree((XtPointer)keyboards);
1993
layout = layouts[i];
1996
layout = layouts[0];
1997
for (i = 0; i < nlist; i++)
1999
XtFree((XtPointer)list);
2000
XtFree((XtPointer)layouts);
2001
XtFree((XtPointer)mouses);
2002
XtFree((XtPointer)keyboards);
2003
xf86removeLayout(XF86Config, layout);
2007
layout = layouts[i];
2009
for (i = 0; i < nlist; i++)
2011
XtFree((XtPointer)list);
2012
XtFree((XtPointer)layouts);
2014
if (layout == NULL) {
2017
layout = (XF86ConfLayoutPtr)XtCalloc(1, sizeof(XF86ConfLayoutRec));
2018
XmuSnprintf(label, sizeof(label), "Layout%d", nlist ? nlist - 2 : 0);
2022
DialogInput("Layout identifier",
2023
"Enter an identifier for your layout definition:",
2025
" Next >>", " Cancel ", 0);
2026
if (identifier == NULL) {
2027
XtFree((XtPointer)layout);
2028
XtFree((XtPointer)mouses);
2029
XtFree((XtPointer)keyboards);
2034
/* So that we can safely change it */
2036
layout = CopyLayout(rlayout);
2040
mouse = keyboard = NULL;
2044
iref = layout->lay_input_lst;
2046
if (strcmp(iref->iref_inputdev->inp_driver, "mouse") == 0) {
2049
if (xf86findOption(iref->iref_option_lst, "CorePointer")) {
2050
mouse = iref->iref_inputdev;
2055
iref = (XF86ConfInputrefPtr)(iref->list.next);
2057
if (mouse == NULL) {
2060
mouse = piref->iref_inputdev;
2061
piref->iref_option_lst =
2062
xf86addNewOption(piref->iref_option_lst,
2063
XtNewString("CorePointer"), NULL);
2067
mref = iref = (XF86ConfInputrefPtr)XtCalloc(1, sizeof(XF86ConfInputrefRec));
2068
iref->iref_inputdev_str = XtNewString(mouse->inp_identifier);
2069
iref->iref_inputdev = mouse;
2070
iref->iref_option_lst =
2071
xf86addNewOption(iref->iref_option_lst,
2072
XtNewString("CorePointer"), NULL);
2073
iref->list.next = layout->lay_input_lst;
2074
if (layout->lay_input_lst == NULL)
2075
layout->lay_input_lst = iref;
2077
iref->list.next = layout->lay_input_lst;
2078
layout->lay_input_lst = iref;
2085
/* XXX list fields are not allocated */
2088
list = (char**)XtMalloc(sizeof(char*));
2089
list[nlist++] = mouse->inp_identifier;
2090
input = XF86Config->conf_input_lst;
2092
if (input != mouse && strcmp(input->inp_driver, "mouse") == 0) {
2093
list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
2094
list[nlist++] = input->inp_identifier;
2096
input = (XF86ConfInputPtr)(input->list.next);
2100
i = DialogMenu("Select Core Pointer",
2101
"Select the mouse connected to you computer",
2102
12, 60, 4, nlist, list, " Ok ", " Cancel ", 0);
2104
XtFree((XtPointer)mouses);
2105
XtFree((XtPointer)keyboards);
2106
XtFree((XtPointer)list);
2107
if (layout->lay_identifier == NULL)
2113
/* Did not select the default one */
2114
iref = layout->lay_input_lst;
2116
if (strcasecmp(iref->iref_inputdev_str, list[i]) == 0) {
2117
if ((option = xf86findOption(iref->iref_option_lst,
2118
"SendCoreEvents")) != NULL) {
2119
XtFree(option->opt_name);
2120
option->opt_name = XtNewString("CorePointer");
2123
iref->iref_option_lst =
2124
xf86addNewOption(iref->iref_option_lst,
2125
"CorePointer", NULL);
2126
option = xf86findOption(mref->iref_option_lst,
2128
XtFree(option->opt_name);
2129
option->opt_name = XtNewString("SendCoreEvents");
2132
iref = (XF86ConfInputrefPtr)(iref->list.next);
2136
/* XXX Write code to add/remove more mouses here */
2142
iref = layout->lay_input_lst;
2144
if (IS_KBDDRIV(iref->iref_inputdev->inp_driver)) {
2145
if (keyboard == NULL)
2147
if (xf86findOption(iref->iref_option_lst, "CoreKeyboard")) {
2148
keyboard = iref->iref_inputdev;
2153
iref = (XF86ConfInputrefPtr)(iref->list.next);
2155
if (keyboard == NULL) {
2158
keyboard = piref->iref_inputdev;
2159
piref->iref_option_lst =
2160
xf86addNewOption(piref->iref_option_lst,
2161
XtNewString("CoreKeyboard"), NULL);
2164
keyboard = keyboards[0];
2165
kref = iref = (XF86ConfInputrefPtr)XtCalloc(1, sizeof(XF86ConfInputrefRec));
2166
iref->iref_inputdev_str = XtNewString(keyboard->inp_identifier);
2167
iref->iref_inputdev = keyboard;
2168
iref->iref_option_lst =
2169
xf86addNewOption(iref->iref_option_lst,
2170
XtNewString("CoreKeyboard"), NULL);
2171
iref->list.next = layout->lay_input_lst;
2172
if (layout->lay_input_lst == NULL)
2173
layout->lay_input_lst = iref;
2175
iref->list.next = layout->lay_input_lst;
2176
layout->lay_input_lst = iref;
2183
/* XXX list fields are not allocated */
2184
if (nkeyboards > 1) {
2186
list = (char**)XtMalloc(sizeof(char*));
2187
list[nlist++] = keyboard->inp_identifier;
2188
input = XF86Config->conf_input_lst;
2190
if (input != keyboard && IS_KBDDRIV(input->inp_driver)) {
2191
list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
2192
list[nlist++] = input->inp_identifier;
2194
input = (XF86ConfInputPtr)(input->list.next);
2198
i = DialogMenu("Select Core Keyboard",
2199
"Select the keyboard connected to you computer",
2200
12, 60, 4, nlist, list, " Ok ", " Cancel ", 0);
2202
XtFree((XtPointer)mouses);
2203
XtFree((XtPointer)keyboards);
2204
XtFree((XtPointer)list);
2205
if (layout->lay_identifier == NULL)
2211
/* Did not select the default one */
2212
iref = layout->lay_input_lst;
2214
if (strcasecmp(iref->iref_inputdev_str, list[i]) == 0) {
2215
if ((option = xf86findOption(iref->iref_option_lst,
2216
"SendCoreEvents")) != NULL) {
2217
XtFree(option->opt_name);
2218
option->opt_name = XtNewString("CoreKeyboard");
2221
iref->iref_option_lst =
2222
xf86addNewOption(iref->iref_option_lst,
2223
"CoreKeyboard", NULL);
2224
option = xf86findOption(kref->iref_option_lst,
2226
XtFree(option->opt_name);
2227
option->opt_name = XtNewString("SendCoreEvents");
2230
iref = (XF86ConfInputrefPtr)(iref->list.next);
2234
/* XXX Write code to add/remove more keyboards here */
2237
XtFree((XtPointer)mouses);
2238
XtFree((XtPointer)keyboards);
2240
/* Just one screen */
2241
if (XF86Config->conf_screen_lst->list.next == NULL) {
2244
Dialog("Layout configuration",
2245
(nmouses > 1 || nkeyboards > 1) ?
2246
"As you have only one screen configured, I can now finish "
2247
"creating this Layout configuration."
2249
"As you have only one screen, mouse and keyboard configured, "
2250
"I can now finish creating this Layout configuration.",
2251
12, 60, " Finish ", NULL, 0);
2257
/* The code below just adds a screen to the right of the last
2258
* one, or allows removing a screen.
2259
* Needs some review, and adding more options.
2264
static char *screen_opts[] = {
2265
"Add a new screen to layout",
2266
"Remove screen from layout",
2267
"Finish layout configuration",
2272
i = DialogMenu("Layout configuration", "Please choose one option:",
2273
12, 60, 3, sizeof(screen_opts) / sizeof(screen_opts[0]),
2274
screen_opts, " Done ", " Cancel all changes ", 2);
2283
/* add new screen */
2288
screen = XF86Config->conf_screen_lst;
2290
adj = layout->lay_adjacency_lst;
2292
if (adj->adj_screen == screen)
2294
adj = (XF86ConfAdjacencyPtr)(adj->list.next);
2297
list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
2298
screens = (XF86ConfScreenPtr*)XtRealloc((XtPointer)screens,
2299
(nlist + 1) * sizeof(XF86ConfScreenPtr));
2300
/* NOT duplicated */
2301
list[nlist] = screen->scrn_identifier;
2302
screens[nlist] = screen;
2305
screen = (XF86ConfScreenPtr)(screen->list.next);
2313
i = DialogMenu("Layout add screen", "Choose screen to add:",
2314
12, 60, 3, nlist, list,
2315
" Add ", " Cancel ", 0);
2317
padj = layout->lay_adjacency_lst;
2318
adj = (XF86ConfAdjacencyPtr)
2319
XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
2320
adj->adj_screen = screens[i];
2322
adj->adj_where = CONF_ADJ_ABSOLUTE;
2323
layout->lay_adjacency_lst = adj;
2326
while (padj->list.next)
2327
padj = (XF86ConfAdjacencyPtr)(padj->list.next);
2328
padj->list.next = adj;
2329
adj->adj_where = CONF_ADJ_RIGHTOF;
2330
adj->adj_refscreen =
2331
XtNewString(padj->adj_screen->scrn_identifier);
2334
XtFree((XtPointer)list);
2335
XtFree((XtPointer)screens);
2338
/* remove a screen */
2343
adj = layout->lay_adjacency_lst;
2346
list = (char**)XtRealloc((XtPointer)list, (nlist + 1) * sizeof(char*));
2347
screens = (XF86ConfScreenPtr*)XtRealloc((XtPointer)screens,
2348
(nlist + 1) * sizeof(XF86ConfScreenPtr));
2349
list[nlist] = adj->adj_screen->scrn_identifier;
2350
screens[nlist] = adj->adj_screen;
2352
adj = (XF86ConfAdjacencyPtr)(adj->list.next);
2360
i = DialogMenu("Layout remove screen", "Choose screen to remove:",
2361
12, 60, 3, nlist, list,
2362
" Remove ", " Cancel ", 0);
2364
adj = padj = layout->lay_adjacency_lst;
2366
if (adj->adj_screen == screens[i]) {
2367
padj = (XF86ConfAdjacencyPtr)(padj->list.next);
2368
if (padj && adj->adj_where == CONF_ADJ_RIGHTOF &&
2369
padj->adj_where == CONF_ADJ_RIGHTOF) {
2370
XtFree(padj->adj_refscreen);
2371
padj->adj_refscreen = XtNewString(adj->adj_refscreen);
2373
xf86removeAdjacency(layout, adj);
2377
adj = (XF86ConfAdjacencyPtr)(padj->list.next);
2379
XtFree((XtPointer)list);
2380
XtFree((XtPointer)screens);
2383
/* finish screen configuration */
2389
if (layout->lay_adjacency_lst == NULL) {
2390
adj = (XF86ConfAdjacencyPtr)XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
2391
adj->adj_screen = XF86Config->conf_screen_lst;
2392
adj->adj_screen_str = XtNewString(XF86Config->conf_screen_lst->scrn_identifier);
2393
adj->adj_where = CONF_ADJ_ABSOLUTE;
2394
layout->lay_adjacency_lst = adj;
2397
/* just edited this layout */
2398
if (nmouses > 1 || nkeyboards > 1) {
2399
XF86ConfAdjacencyPtr tadj = rlayout->lay_adjacency_lst;
2400
XF86ConfInactivePtr tinac = rlayout->lay_inactive_lst;
2401
XF86ConfInputrefPtr tinp = rlayout->lay_input_lst;
2403
rlayout->lay_adjacency_lst = layout->lay_adjacency_lst;
2404
rlayout->lay_inactive_lst = layout->lay_inactive_lst;
2405
rlayout->lay_input_lst = layout->lay_input_lst;
2407
layout->lay_adjacency_lst = tadj;
2408
layout->lay_inactive_lst = tinac;
2409
layout->lay_input_lst = tinp;
2415
layout->lay_identifier = identifier;
2416
XF86Config->conf_layout_lst =
2417
xf86addLayout(XF86Config->conf_layout_lst, layout);
2428
wattrset(stdscr, screen_attr);
2429
for (i = 0; i < LINES; i++) {
2430
wmove(stdscr, i, 0);
2431
for (j = 0; j < COLS; j++)
2432
waddch(stdscr, ACS_PLUS);
2438
Dialog(char *title, char * prompt, int height, int width,
2439
char *label1, char *label2, int button)
2441
int x, x1, x2, y, key, l1len, l2len;
2444
x = (COLS - width) / 2;
2445
y = (LINES - height) / 2;
2447
dialog = newwin(height, width, y, x);
2448
keypad(dialog, TRUE);
2450
PaintWindow(dialog, title, 0, 0, height, width);
2451
wattrset(dialog, dialog_attr);
2452
PrintWrap(dialog, prompt, width - 3, 2, 3);
2454
l1len = strlen(label1);
2456
l2len = strlen(label2);
2461
x1 = (width - (l1len + l2len)) / (label2 ? 3 : 2);
2462
x2 = x1 + x1 + l1len;
2466
PaintButton(dialog, label2, y, x2, FALSE);
2467
PaintButton(dialog, label1, y, x1, TRUE);
2470
PaintButton(dialog, label1, y, x1, FALSE);
2472
PaintButton(dialog, label2, y, x2, TRUE);
2478
key = wgetch(dialog);
2485
PaintButton(dialog, label1, y, x1, FALSE);
2486
PaintButton(dialog, label2, y, x2, TRUE);
2493
PaintButton(dialog, label2, y, x2, FALSE);
2494
PaintButton(dialog, label1, y, x1, TRUE);
2510
PaintWindow(WINDOW *win, char *title_str, int y, int x, int height, int width)
2514
if (title_str != NULL) {
2515
j = (width - strlen(title_str)) / 2 - 1;
2517
wattrset(win, title_attr);
2519
for (i = 0; i < j; i++)
2521
waddstr(win, title_str);
2522
for (; i < width; i++)
2528
for (i = 1; i < height; i++) {
2529
wmove(win, y + i, x);
2530
for (j = 0; j < width; j++)
2531
if (i == height - 1 && !j)
2532
waddch(win, highlight_border_attr | ACS_LLCORNER);
2533
else if (i == height - 1 && j == width - 1)
2534
waddch(win, shadow_border_attr | ACS_LRCORNER);
2535
else if (i == height - 1)
2536
waddch(win, shadow_border_attr | ACS_HLINE);
2538
waddch(win, highlight_border_attr | ACS_VLINE);
2539
else if (j == width - 1)
2540
waddch(win, shadow_border_attr | ACS_VLINE);
2542
waddch(win, dialog_attr | ' ');
2548
PaintBox(WINDOW *win, int y, int x, int height, int width)
2554
for (i = 0; i < height; i++) {
2555
wmove(win, y + i, x);
2556
for (j = 0; j < width; j++)
2558
waddch(win, shadow_border_attr | ACS_ULCORNER);
2559
else if (i == height - 1 && !j)
2560
waddch(win, shadow_border_attr | ACS_LLCORNER);
2561
else if (!i && j == width-1)
2562
waddch(win, highlight_border_attr | ACS_URCORNER);
2563
else if (i == height - 1 && j == width - 1)
2564
waddch(win, highlight_border_attr | ACS_LRCORNER);
2566
waddch(win, shadow_border_attr | ACS_HLINE);
2567
else if (i == height - 1)
2568
waddch(win, highlight_border_attr | ACS_HLINE);
2570
waddch(win, shadow_border_attr | ACS_VLINE);
2571
else if (j == width - 1)
2572
waddch(win, highlight_border_attr | ACS_VLINE);
2574
waddch(win, dialog_attr | ' ');
2580
PaintButton(WINDOW *win, char *label, int y, int x, int selected)
2585
wattrset(win, selected ? button_active_attr : button_inactive_attr);
2586
waddstr(win, selected ? "[" : " ");
2587
temp = strspn(label, " ");
2589
wattrset(win, selected ? button_active_attr : button_inactive_attr);
2590
for (i = 0; i < temp; i++)
2592
wattrset(win, selected ? button_active_attr : button_inactive_attr);
2593
waddch(win, label[0]);
2594
wattrset(win, selected ? button_active_attr : button_inactive_attr);
2595
waddstr(win, label + 1);
2596
wattrset(win, selected ? button_active_attr : button_inactive_attr);
2597
waddstr(win, selected ? "]" : " ");
2598
wmove(win, y, x + temp + 1);
2602
PrintWrap(WINDOW *win, char *prompt, int width, int y, int x)
2604
int cur_x, cur_y, len, yinc;
2605
char *word, *tempstr = XtMalloc(strlen(prompt) + 1);
2610
while (*prompt == '\n') {
2615
strcpy(tempstr, prompt);
2617
for (word = strtok(tempstr, " \n"); word != NULL; word = strtok(NULL, " \n")) {
2620
while (prompt[word - tempstr + len + yinc] == '\n')
2622
if (cur_x + strlen(word) > width) {
2626
wmove(win, cur_y, cur_x);
2628
getyx(win, cur_y, cur_x);
2641
DialogMenu(char *title, char *prompt, int height, int width, int menu_height,
2642
int item_no, char **items, char *label1, char *label2, int choice)
2644
int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0,
2645
scrlx = 0, max_choice, nscroll, max_scroll, x1, x2, l1len, l2len;
2646
WINDOW *dialog, *menu;
2648
max_choice = MIN(menu_height, item_no);
2649
max_scroll = MAX(0, item_no - max_choice);
2651
x = (COLS - width) / 2;
2652
y = (LINES - height) / 2;
2654
dialog = newwin(height, width, y, x);
2655
keypad(dialog, TRUE);
2657
PaintWindow(dialog, title, 0, 0, height, width);
2659
wattrset(dialog, dialog_attr);
2660
PrintWrap(dialog, prompt, width - 3, 2, 3);
2662
l1len = strlen(label1);
2663
l2len = strlen(label2);
2665
x1 = (width - (l1len + l2len)) / 3;
2666
x2 = x1 + x1 + l1len;
2668
menu_width = width - 6;
2669
getyx(dialog, cur_y, cur_x);
2671
box_x = (width - menu_width) / 2 - 1;
2673
menu = subwin(dialog, menu_height, menu_width, y + box_y + 1, x + box_x + 1);
2676
/* draw a box around the menu items */
2677
PaintBox(dialog, box_y, box_x, menu_height + 2, menu_width + 2);
2681
if (choice > menu_height) {
2682
scrlx = MIN(max_scroll, choice);
2686
for (i = 0; i < max_choice; i++)
2687
PaintItem(menu, items[i + scrlx], i, i == choice);
2688
PaintScroller(menu, scrlx + choice, item_no, menu_height);
2693
PaintButton(dialog, label2, y, x2, FALSE);
2694
PaintButton(dialog, label1, y, x1, TRUE);
2700
key = wgetch(dialog);
2702
if (menu_height > 1 && key == KEY_PPAGE) {
2705
/* Scroll menu down */
2706
getyx(dialog, cur_y, cur_x);
2708
nscroll = max_choice > scrlx ? -scrlx : -max_choice;
2709
scrollok(menu, TRUE);
2710
wscrl(menu, nscroll);
2711
scrollok(menu, FALSE);
2713
PaintItem(menu, items[i = scrlx + nscroll], 0, TRUE);
2714
for (++i; i <= scrlx; i++)
2715
PaintItem(menu, items[i], i - (scrlx + nscroll), FALSE);
2717
PaintScroller(menu, scrlx + choice, item_no, menu_height);
2725
else if (menu_height > 1 && key == KEY_NPAGE) {
2726
if (choice == max_choice - 1) {
2727
if (scrlx < max_scroll) {
2728
/* Scroll menu up */
2729
getyx(dialog, cur_y, cur_x);
2731
nscroll = (scrlx + max_choice > max_scroll ?
2732
max_scroll : scrlx + max_choice) - scrlx;
2733
scrollok(menu, TRUE);
2734
wscrl(menu, nscroll);
2735
scrollok(menu, FALSE);
2738
for (i = 0; i < max_choice - 1; i++)
2739
PaintItem(menu, items[i + scrlx], i, FALSE);
2740
PaintItem(menu, items[i + scrlx], max_choice - 1, TRUE);
2741
PaintScroller(menu, scrlx + choice, item_no, menu_height);
2749
else if (key == KEY_UP) {
2752
/* Scroll menu down */
2753
getyx(dialog, cur_y, cur_x);
2754
if (menu_height > 1) {
2755
PaintItem(menu, items[scrlx], 0, FALSE);
2756
scrollok(menu, TRUE);
2758
scrollok(menu, FALSE);
2761
PaintItem(menu, items[scrlx], 0, TRUE);
2762
PaintScroller(menu, scrlx + choice, item_no, menu_height);
2771
else if (key == KEY_DOWN) {
2772
if (choice == max_choice - 1) {
2773
if (scrlx + choice < item_no - 1) {
2774
/* Scroll menu up */
2775
getyx(dialog, cur_y, cur_x);
2776
if (menu_height > 1) {
2777
PaintItem(menu, items[scrlx + max_choice - 1], max_choice - 1, FALSE);
2778
scrollok(menu, TRUE);
2780
scrollok(menu, FALSE);
2783
PaintItem(menu, items[scrlx + max_choice - 1], max_choice - 1, TRUE);
2784
PaintScroller(menu, scrlx + choice, item_no, menu_height);
2791
i = MIN(choice + 1, item_no - 1);
2795
getyx(dialog, cur_y, cur_x);
2796
PaintItem(menu, items[scrlx + choice], choice, FALSE);
2799
PaintItem(menu, items[scrlx + choice], choice, TRUE);
2800
PaintScroller(menu, scrlx + choice, item_no, menu_height);
2802
wmove(dialog, cur_y, cur_x);
2813
PaintButton(dialog, label1, y, x1, FALSE);
2814
PaintButton(dialog, label2, y, x2, TRUE);
2818
PaintButton(dialog, label2, y, x2, FALSE);
2819
PaintButton(dialog, label1, y, x1, TRUE);
2827
return (!button ? scrlx + choice : -1);
2829
for (i = scrlx + choice + 1; i < item_no; i++)
2830
if (toupper(items[i][0]) == toupper(key))
2833
for (i = 0; i < scrlx + choice; i++)
2834
if (toupper(items[i][0]) == toupper(key))
2837
getyx(dialog, cur_y, cur_x);
2838
if (i < item_no && i != scrlx + choice) {
2839
if (i >= scrlx && i < scrlx + max_choice) {
2840
/* it is already visible */
2841
PaintItem(menu, items[scrlx + choice], choice, FALSE);
2845
scrlx = MIN(i, max_scroll);
2847
for (i = 0; i < max_choice; i++)
2849
PaintItem(menu, items[scrlx + i], i, FALSE);
2851
PaintItem(menu, items[scrlx + choice], choice, TRUE);
2852
PaintScroller(menu, scrlx + choice, item_no, menu_height);
2854
wmove(dialog, cur_y, cur_x);
2864
PaintItem(WINDOW *win, char *item, int choice, int selected)
2868
wattrset(win, selected ? title_attr : dialog_attr);
2869
wmove(win, choice, 1);
2870
for (i = 1; i < menu_width; i++)
2872
wmove(win, choice, item_x);
2873
wattrset(win, selected ? title_attr : dialog_attr);
2878
PaintScroller(WINDOW *win, int offset, int lenght, int visible)
2882
if (lenght > visible)
2883
pos = (visible / (double)lenght) * offset;
2886
wattrset(win, shadow_border_attr);
2887
for (i = 0; i < visible; i++) {
2889
waddch(win, i == pos ? ACS_BLOCK : ACS_VLINE);
2894
DialogCheckBox(char *title, char *prompt, int height, int width, int menu_height,
2895
int item_no, char **items, char *label1, char *label2, char *checks)
2897
int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
2898
scrlx = 0, max_choice, nscroll, max_scroll, x1, x2, l1len, l2len;
2899
WINDOW *dialog, *menu;
2901
max_choice = MIN(menu_height, item_no);
2902
max_scroll = MAX(0, item_no - max_choice);
2904
x = (COLS - width) / 2;
2905
y = (LINES - height) / 2;
2907
dialog = newwin(height, width, y, x);
2908
keypad(dialog, TRUE);
2910
PaintWindow(dialog, title, 0, 0, height, width);
2912
wattrset(dialog, dialog_attr);
2913
PrintWrap(dialog, prompt, width - 3, 2, 3);
2915
l1len = strlen(label1);
2916
l2len = strlen(label2);
2918
x1 = (width - (l1len + l2len)) / 3;
2919
x2 = x1 + x1 + l1len;
2921
menu_width = width - 6;
2922
getyx(dialog, cur_y, cur_x);
2924
box_x = (width - menu_width) / 2 - 1;
2926
menu = subwin(dialog, menu_height, menu_width, y + box_y + 1, x + box_x + 1);
2929
/* draw a box around the menu items */
2930
PaintBox(dialog, box_y, box_x, menu_height + 2, menu_width + 2);
2934
for (i = 0; i < max_choice; i++)
2935
PaintCheckItem(menu, items[i + scrlx], i, i == 0, checks[i + scrlx]);
2936
PaintScroller(menu, scrlx + choice, item_no, menu_height);
2941
PaintButton(dialog, label2, y, x2, FALSE);
2942
PaintButton(dialog, label1, y, x1, TRUE);
2948
key = wgetch(dialog);
2950
if (menu_height > 1 && key == KEY_PPAGE) {
2953
/* Scroll menu down */
2954
getyx(dialog, cur_y, cur_x);
2956
nscroll = max_choice > scrlx ? -scrlx : -max_choice;
2957
scrollok(menu, TRUE);
2958
wscrl(menu, nscroll);
2959
scrollok(menu, FALSE);
2961
i = scrlx + nscroll;
2962
PaintCheckItem(menu, items[i], 0, TRUE, checks[i]);
2963
for (++i; i <= scrlx; i++)
2964
PaintCheckItem(menu, items[i], i - (scrlx + nscroll), FALSE, checks[i]);
2966
PaintScroller(menu, scrlx + choice, item_no, menu_height);
2974
else if (menu_height > 1 && key == KEY_NPAGE) {
2975
if (choice == max_choice - 1) {
2976
if (scrlx < max_scroll) {
2977
/* Scroll menu up */
2978
getyx(dialog, cur_y, cur_x);
2980
nscroll = (scrlx + max_choice > max_scroll ?
2981
max_scroll : scrlx + max_choice) - scrlx;
2982
scrollok(menu, TRUE);
2983
wscrl(menu, nscroll);
2984
scrollok(menu, FALSE);
2987
for (i = 0; i < max_choice - 1; i++)
2988
PaintCheckItem(menu, items[i + scrlx], i, FALSE, checks[i + scrlx]);
2989
PaintCheckItem(menu, items[i + scrlx], max_choice - 1, TRUE, checks[i + scrlx]);
2990
PaintScroller(menu, scrlx + choice, item_no, menu_height);
2998
else if (key == KEY_UP) {
3001
/* Scroll menu down */
3002
getyx(dialog, cur_y, cur_x);
3003
if (menu_height > 1) {
3004
PaintCheckItem(menu, items[scrlx], 0, FALSE, checks[scrlx]);
3005
scrollok(menu, TRUE);
3007
scrollok(menu, FALSE);
3010
PaintCheckItem(menu, items[scrlx], 0, TRUE, checks[scrlx]);
3011
PaintScroller(menu, scrlx + choice, item_no, menu_height);
3020
else if (key == KEY_DOWN) {
3021
if (choice == max_choice - 1) {
3022
if (scrlx + choice < item_no - 1) {
3023
/* Scroll menu up */
3024
getyx(dialog, cur_y, cur_x);
3025
if (menu_height > 1) {
3026
PaintCheckItem(menu, items[scrlx + max_choice - 1], max_choice - 1, FALSE, checks[scrlx + max_choice - 1]);
3027
scrollok(menu, TRUE);
3029
scrollok(menu, FALSE);
3032
PaintCheckItem(menu, items[scrlx + max_choice - 1], max_choice - 1, TRUE, checks[scrlx + max_choice - 1]);
3033
PaintScroller(menu, scrlx + choice, item_no, menu_height);
3040
i = MIN(choice + 1, item_no - 1);
3044
getyx(dialog, cur_y, cur_x);
3045
PaintCheckItem(menu, items[scrlx + choice], choice, FALSE, checks[scrlx + choice]);
3048
PaintCheckItem(menu, items[scrlx + choice], choice, TRUE, checks[scrlx + choice]);
3049
PaintScroller(menu, scrlx + choice, item_no, menu_height);
3051
wmove(dialog, cur_y, cur_x);
3062
PaintButton(dialog, label1, y, x1, FALSE);
3063
PaintButton(dialog, label2, y, x2, TRUE);
3067
PaintButton(dialog, label2, y, x2, FALSE);
3068
PaintButton(dialog, label1, y, x1, TRUE);
3073
getyx(dialog, cur_y, cur_x);
3074
checks[scrlx + choice] = !checks[scrlx + choice];
3075
PaintCheckItem(menu, items[scrlx + choice], choice, TRUE, checks[scrlx + choice]);
3076
wmove(dialog, cur_y, cur_x);
3083
return (!button ? 0 : -1);
3085
for (i = scrlx + choice + 1; i < item_no; i++)
3086
if (toupper(items[i][0]) == toupper(key))
3089
for (i = 0; i < scrlx + choice; i++)
3090
if (toupper(items[i][0]) == toupper(key))
3093
getyx(dialog, cur_y, cur_x);
3094
if (i < item_no && i != scrlx + choice) {
3095
if (i >= scrlx && i < scrlx + max_choice) {
3096
/* it is already visible */
3097
PaintCheckItem(menu, items[scrlx + choice], choice, FALSE, checks[scrlx + choice]);
3101
scrlx = MIN(i, max_scroll);
3103
for (i = 0; i < max_choice; i++)
3105
PaintCheckItem(menu, items[scrlx + i], i, FALSE, checks[scrlx + i]);
3107
PaintCheckItem(menu, items[scrlx + choice], choice, TRUE, checks[scrlx + choice]);
3108
PaintScroller(menu, scrlx + choice, item_no, menu_height);
3110
wmove(dialog, cur_y, cur_x);
3120
PaintCheckItem(WINDOW *win, char *item, int choice, int selected, int checked)
3124
wattrset(win, selected ? title_attr : dialog_attr);
3125
wmove(win, choice, 1);
3126
for (i = 1; i < menu_width; i++)
3128
wmove(win, choice, item_x);
3129
wattrset(win, selected ? title_attr : dialog_attr);
3130
wprintw(win, "[%c] ", checked ? 'X' : ' ');
3135
DialogInput(char *title, char *prompt, int height, int width, char *init,
3136
char *label1, char *label2, int def_button)
3138
int i, x, y, box_y, box_x, box_width, len,
3139
input_x = 0, scrlx = 0, key = 0, button = -1, x1, x2, l1len, l2len;
3140
char instr[1024 + 1];
3143
x = (COLS - width) / 2;
3144
y = (LINES - height) / 2;
3146
dialog = newwin(height, width, y, x);
3147
keypad(dialog, TRUE);
3149
PaintWindow(dialog, title, 0, 0, height, width);
3151
wattrset(dialog, dialog_attr);
3152
PrintWrap(dialog, prompt, width - 3, 2, 3);
3154
l1len = strlen(label1);
3155
l2len = strlen(label2);
3157
x1 = (width - (l1len + l2len)) / 3;
3158
x2 = x1 + x1 + l1len;
3160
box_width = width - 6;
3161
getyx(dialog, y, x);
3163
box_x = (width - box_width) / 2;
3164
PaintBox(dialog, y + 1, box_x - 1, 3, box_width + 2);
3168
PaintButton(dialog, label2, y, x2, def_button == 1);
3169
PaintButton(dialog, label1, y, x1, def_button == 0);
3171
memset(instr, '\0', sizeof(instr));
3172
wmove(dialog, box_y, box_x);
3173
wattrset(dialog, dialog_attr);
3175
strncpy(instr, init, sizeof(instr) - 2);
3177
input_x = len = strlen(instr);
3178
if (input_x >= box_width) {
3179
scrlx = input_x - box_width + 1;
3180
input_x = box_width - 1;
3181
for (i = 0; i < box_width - 1; i++)
3182
waddch(dialog, instr[scrlx + i]);
3185
waddstr(dialog, instr);
3187
wmove(dialog, box_y, box_x + input_x);
3192
key = wgetch(dialog);
3193
if (button == -1) { /* Input box selected */
3200
if (scrlx && !input_x) {
3202
wmove(dialog, box_y, box_x);
3203
for (i = 0; i < box_width; i++)
3204
waddch(dialog, instr[scrlx + input_x + i] ? instr[scrlx + input_x + i] : ' ');
3205
wmove(dialog, box_y, input_x + box_x);
3209
wmove(dialog, box_y, --input_x + box_x);
3214
if (input_x + scrlx < len) {
3215
if (input_x == box_width - 1) {
3217
wmove(dialog, box_y, box_x);
3218
for (i = scrlx; i < scrlx + box_width; i++)
3219
waddch(dialog, instr[i] ? instr[i] : ' ');
3220
wmove(dialog, box_y, input_x + box_x);
3224
wmove(dialog, box_y, ++input_x + box_x);
3231
#if defined(__SCO__) || defined(__UNIXWARE__)
3234
if (input_x || scrlx) {
3235
wattrset(dialog, dialog_attr);
3237
if (scrlx + input_x < len)
3238
memmove(instr + scrlx + input_x - 1,
3239
instr + scrlx + input_x,
3240
len - (scrlx + input_x));
3241
instr[--len] = '\0';
3244
scrlx = scrlx < box_width - 1 ? 0 : scrlx - (box_width - 1);
3245
wmove(dialog, box_y, box_x);
3246
for (i = 0; i < box_width; i++)
3247
waddch(dialog, instr[scrlx + input_x + i] ? instr[scrlx + input_x + i] : ' ');
3248
input_x = len - scrlx;
3251
wmove(dialog, box_y, --input_x + box_x);
3252
for (i = scrlx + input_x; i < len &&
3253
i < scrlx + box_width; i++)
3254
waddch(dialog, instr[i]);
3255
if (i < scrlx + box_width)
3256
waddch(dialog, ' ');
3258
wmove(dialog, box_y, input_x + box_x);
3264
wmove(dialog, box_y, box_x);
3267
for (i = 0; i < box_width; i++)
3268
waddch(dialog, instr[i] ? instr[i] : ' ');
3271
wmove(dialog, box_y, box_x);
3275
if (input_x + scrlx < len) {
3276
memmove(instr + scrlx + input_x,
3277
instr + scrlx + input_x + 1,
3278
len - (scrlx + input_x));
3279
instr[--len] = '\0';
3280
for (i = scrlx + input_x; i < len &&
3281
i < scrlx + box_width; i++)
3282
waddch(dialog, instr[i]);
3283
if (i < scrlx + box_width)
3284
waddch(dialog, ' ');
3285
wmove(dialog, box_y, input_x + box_x);
3291
if (box_width + scrlx < len) {
3292
input_x = box_width - 1;
3293
scrlx = len - box_width + 1;
3294
wmove(dialog, box_y, box_x);
3295
for (i = scrlx; i < scrlx + box_width; i++)
3296
waddch(dialog, instr[i] ? instr[i] : ' ');
3297
wmove(dialog, box_y, input_x + box_x);
3301
input_x = len - scrlx;
3302
wmove(dialog, box_y, input_x + box_x);
3308
for (i = input_x; i < box_width; i++)
3309
waddch(dialog, ' ');
3310
for (i = scrlx + input_x; i < len; i++)
3312
len = scrlx + input_x;
3313
wmove(dialog, box_y, box_x + input_x);
3318
if (key < 0x100 && isprint(key)) {
3319
if (scrlx + input_x < sizeof(instr) - 1) {
3320
wattrset(dialog, dialog_attr);
3321
if (scrlx + input_x < len) {
3322
memmove(instr + scrlx + input_x + 1,
3323
instr + scrlx + input_x,
3324
len - (scrlx + input_x));
3326
instr[scrlx + input_x] = key;
3327
instr[++len] = '\0';
3328
if (input_x == box_width - 1) {
3330
wmove(dialog, box_y, box_x);
3331
for (i = 0; i < box_width - 1; i++)
3332
waddch(dialog, instr[scrlx + i]);
3335
wmove(dialog, box_y, input_x++ + box_x);
3336
for (i = scrlx + input_x - 1; i < len &&
3337
i < scrlx + box_width; i++)
3338
waddch(dialog, instr[i]);
3339
wmove(dialog, box_y, input_x + box_x);
3344
flash(); /* Alarm user about overflow */
3355
button = 1; /* Indicates "Cancel" button is selected */
3356
PaintButton(dialog, label1, y, x1, FALSE);
3357
PaintButton(dialog, label2, y, x2, TRUE);
3361
button = -1; /* Indicates input box is selected */
3362
PaintButton(dialog, label2, y, x2, FALSE);
3363
PaintButton(dialog, label1, y, x1, TRUE);
3364
wmove(dialog, box_y, box_x + input_x);
3368
button = 0; /* Indicates "OK" button is selected */
3369
PaintButton(dialog, label2, y, x2, FALSE);
3370
PaintButton(dialog, label1, y, x1, TRUE);
3380
button = 0; /* Indicates "OK" button is selected */
3381
PaintButton(dialog, label2, y, x2, FALSE);
3382
PaintButton(dialog, label1, y, x1, TRUE);
3386
button = 1; /* Indicates "Cancel" button is selected */
3387
PaintButton(dialog, label1, y, x1, FALSE);
3388
PaintButton(dialog, label2, y, x2, TRUE);
3392
button = -1; /* Indicates input box is selected */
3393
PaintButton(dialog, label2, y, x2, FALSE);
3394
PaintButton(dialog, label1, y, x1, TRUE);
3395
wmove(dialog, box_y, box_x + input_x);
3404
return (button != 1 ? XtNewString(instr) : NULL);