~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/xfree86/utils/xorgcfg/text-mode.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XdotOrg: xserver/xorg/hw/xfree86/utils/xorgcfg/text-mode.c,v 1.6 2005/12/08 17:54:40 kem Exp $ */
 
2
/*
 
3
 * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
 
4
 * 
 
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:
 
11
 * 
 
12
 * The above copyright notice and this permission notice shall be included in
 
13
 * all copies or substantial portions of the Software.
 
14
 *  
 
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
 
21
 * SOFTWARE.
 
22
 * 
 
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
 
26
 * Conectiva Linux.
 
27
 *
 
28
 * Author: Paulo CĆ©sar Pereira de Andrade <pcpa@conectiva.com.br>
 
29
 *
 
30
 * $XFree86: xc/programs/Xserver/hw/xfree86/xf86cfg/text-mode.c,v 1.25 2003/11/12 00:10:30 dawes Exp $
 
31
 */
 
32
 
 
33
#include <stdio.h>
 
34
#include <stdlib.h>
 
35
#include <string.h>
 
36
#if defined(__SCO__) || defined(__UNIXWARE__) || \
 
37
        (defined(sun) && defined(__SVR4))
 
38
#include <curses.h>
 
39
#else
 
40
#include <ncurses.h>
 
41
#endif
 
42
#include <ctype.h>
 
43
#include <X11/Xlib.h>
 
44
#include <X11/extensions/XKBstr.h>
 
45
#include <X11/extensions/XKBrules.h>
 
46
#include "cards.h"
 
47
#include "config.h"
 
48
#include "xf86config.h"
 
49
#include "loader.h"
 
50
 
 
51
#define IS_KBDDRIV(X) ((strcmp((X),"kbd") == 0) || \
 
52
        (strcmp((X), "keyboard") == 0))
 
53
 
 
54
#ifndef PROJECT_ROOT
 
55
#define PROJECT_ROOT "/usr/X11R6"
 
56
#endif
 
57
 
 
58
#ifndef XKB_RULES_DIR
 
59
#ifndef __UNIXOS2__
 
60
#define XKB_RULES_DIR PROJECT_ROOT "/lib/X11/xkb/rules"
 
61
#else
 
62
#define XKB_RULES_DIR XF86CONFIGDIR "/xkb/rules"
 
63
#endif
 
64
#endif
 
65
 
 
66
#define CONTROL_A       1
 
67
#define CONTROL_D       4
 
68
#define CONTROL_E       5
 
69
#define CONTROL_K       11
 
70
#define TAB     9
 
71
#define MIN(a, b)       ((a) < (b) ? (a) : (b))
 
72
#define MAX(a, b)       ((a) > (b) ? (a) : (b))
 
73
 
 
74
void TextMode(void);
 
75
 
 
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);
 
88
 
 
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);
 
96
 
 
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);
 
102
 
 
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);
 
107
 
 
108
static Bool newconfig;
 
109
 
 
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 ";
 
119
 
 
120
static char *main_menu[] = {
 
121
#define CONF_MOUSE      0
 
122
    "Configure mouse",
 
123
#define CONF_KEYBOARD   1
 
124
    "Configure keyboard",
 
125
#define CONF_MONITOR    2
 
126
    "Configure monitor",
 
127
#define CONF_CARD       3
 
128
    "Configure card",
 
129
#define CONF_SCREEN     4
 
130
    "Configure screen",
 
131
#define CONF_LAYOUT     5
 
132
    "Configure layout",
 
133
#define CONF_FINISH     6
 
134
    "Write "__XCONFIGFILE__" and quit",
 
135
#define CONF_QUIT       7
 
136
    "Quit",
 
137
};
 
138
 
 
139
void
 
140
TextMode(void)
 
141
{
 
142
    static int first = 1;
 
143
    int i, choice = CONF_MOUSE;
 
144
 
 
145
#ifdef USE_MODULES
 
146
    if (!nomodules)
 
147
        LoaderInitializeOptions();
 
148
#endif
 
149
    initscr();
 
150
    noecho();
 
151
    nonl();
 
152
    keypad(stdscr, TRUE);
 
153
 
 
154
    if (first) {
 
155
        const char *filename;
 
156
 
 
157
        first = 0;
 
158
 
 
159
        if (has_colors()) {
 
160
            start_color();
 
161
            init_pair(1, COLOR_BLACK, COLOR_BLACK);
 
162
            screen_attr = A_BOLD | COLOR_PAIR(1);
 
163
 
 
164
            init_pair(2, COLOR_BLACK, COLOR_WHITE);
 
165
            dialog_attr = COLOR_PAIR(2);
 
166
 
 
167
            init_pair(3, COLOR_BLACK, COLOR_WHITE);
 
168
            shadow_border_attr = A_BOLD | COLOR_PAIR(3);
 
169
 
 
170
            init_pair(4, COLOR_WHITE, COLOR_WHITE);
 
171
            highlight_border_attr = A_BOLD | COLOR_PAIR(4);
 
172
 
 
173
            init_pair(5, COLOR_WHITE, COLOR_BLUE);
 
174
            title_attr = A_BOLD | COLOR_PAIR(5);
 
175
            button_active_attr = title_attr;
 
176
 
 
177
            init_pair(6, COLOR_WHITE, COLOR_BLACK);
 
178
            button_inactive_attr = A_BOLD | COLOR_PAIR(6);
 
179
        }
 
180
 
 
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) {
 
186
                ClearScreen();
 
187
                refresh();
 
188
                Dialog("Configuration error",
 
189
                       "Error parsing configuration file.",
 
190
                       7, 50, "  Ok  ", NULL, 0);
 
191
            }
 
192
        }
 
193
        if (XF86Config == NULL) {
 
194
            XF86Config = (XF86ConfigPtr)XtCalloc(1, sizeof(XF86ConfigRec));
 
195
            newconfig = True;
 
196
        }
 
197
        else
 
198
            newconfig = False;
 
199
    }
 
200
 
 
201
    ClearScreen();
 
202
    refresh();
 
203
 
 
204
    /*CONSTCOND*/
 
205
    while (1) {
 
206
        int cancel = FALSE;
 
207
 
 
208
        ClearScreen();
 
209
        refresh();
 
210
        if (Dialog( __XSERVERNAME__" Configuration",
 
211
                   "This program will create the "__XCONFIGFILE__" file, based on "
 
212
                   "menu selections you make.\n"
 
213
                   "\n"
 
214
#if defined(__SCO__) || defined(__UNIXWARE__)
 
215
                   "The "__XCONFIGFILE__" file usually resides in /etc. A "
 
216
                   "sample "__XCONFIGFILE__" file is supplied with "
 
217
#else
 
218
#ifndef __UNIXOS2__
 
219
                   "The "__XCONFIGFILE__" file usually resides in " PROJECT_ROOT "/etc/X11 "
 
220
#else
 
221
                   "The "__XCONFIGFILE__" file usually resides in "XF86CONFIGDIR" "
 
222
#endif
 
223
                   "or /etc/X11. A sample "__XCONFIGFILE__" file is supplied with "
 
224
#endif
 
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"
 
228
                   "\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 "
 
232
                   "fine-tune it.",
 
233
                   20, 60, "   Ok   ", " Cancel ", 0) != 0)
 
234
            break;
 
235
 
 
236
            while (!cancel) {
 
237
                ClearScreen();
 
238
                refresh();
 
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)) {
 
244
                    case CONF_MOUSE:
 
245
                        i = MouseConfig();
 
246
                        if (i > 0 && choice == CONF_MOUSE)
 
247
                            choice = CONF_KEYBOARD;
 
248
                        else if (i == 0)
 
249
                            choice = CONF_MOUSE;
 
250
                        break;
 
251
                    case CONF_KEYBOARD:
 
252
                        i = KeyboardConfig();
 
253
                        if (i > 0 && choice <= CONF_KEYBOARD)
 
254
                            choice = CONF_MONITOR;
 
255
                        else if (i == 0)
 
256
                            choice = CONF_KEYBOARD;
 
257
                        break;
 
258
                    case CONF_MONITOR:
 
259
                        i = MonitorConfig();
 
260
                        if (i > 0 && choice <= CONF_MONITOR)
 
261
                            choice = CONF_CARD;
 
262
                        else if (i == 0)
 
263
                            choice = CONF_MONITOR;
 
264
                        break;
 
265
                    case CONF_CARD:
 
266
                        i = CardConfig();
 
267
                        if (i > 0 && choice <= CONF_CARD)
 
268
                            choice = CONF_SCREEN;
 
269
                        else if (i == 0)
 
270
                            choice = CONF_CARD;
 
271
                        break;
 
272
                    case CONF_SCREEN:
 
273
                        i = ScreenConfig();
 
274
                        if (i > 0 && choice <= CONF_SCREEN)
 
275
                            choice = CONF_LAYOUT;
 
276
                        else if (i == 0)
 
277
                            choice = CONF_SCREEN;
 
278
                        break;
 
279
                    case CONF_LAYOUT:
 
280
                        i = LayoutConfig();
 
281
                        if (i > 0 && choice <= CONF_LAYOUT)
 
282
                            choice = CONF_FINISH;
 
283
                        else if (i == 0)
 
284
                            choice = CONF_LAYOUT;
 
285
                        break;
 
286
                    case CONF_FINISH:
 
287
                        if (WriteXF86Config() < 0)
 
288
                            break;
 
289
                    /*FALLTROUGH*/
 
290
                    case CONF_QUIT:
 
291
                        endwin();
 
292
                        exit(0);
 
293
                    default:
 
294
                        cancel = TRUE;
 
295
                        break;
 
296
                }
 
297
        }
 
298
    }
 
299
 
 
300
    endwin();
 
301
}
 
302
 
 
303
static int
 
304
WriteXF86Config(void)
 
305
{
 
306
    char *xf86config;
 
307
 
 
308
    ClearScreen();
 
309
    refresh();
 
310
    xf86config = DialogInput("Write "__XCONFIGFILE__, "Write configuration to file:",
 
311
                             10, 60, XF86Config_path ? XF86Config_path :
 
312
#ifndef __UNIXOS2__
 
313
                             "/etc/X11/"__XCONFIGFILE__, "  Ok  ", " Cancel ", 0);
 
314
#else
 
315
                             XF86CONFIGDIR"/"__XCONFIGFILE__, "  Ok  ", " Cancel ", 0);
 
316
#endif
 
317
 
 
318
    if (xf86config == NULL)
 
319
        return (-1);
 
320
 
 
321
    if (newconfig) {
 
322
        if (XF86Config->conf_modules == NULL) {
 
323
            static char *modules[] = {"extmod", "glx", "dri", "dbe",
 
324
                                      "record", "xtrap", "type1", "speedo"};
 
325
            XF86LoadPtr load;
 
326
            int i;
 
327
 
 
328
            XF86Config->conf_modules = (XF86ConfModulePtr)
 
329
                XtCalloc(1, sizeof(XF86ConfModuleRec));
 
330
 
 
331
            XF86Config->conf_modules->mod_comment =
 
332
                XtNewString("\tLoad \"freetype\"\n"
 
333
                            "\t# Load \"xtt\"\n");
 
334
 
 
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);
 
340
            }
 
341
        }
 
342
    }
 
343
 
 
344
    if (!xf86writeConfigFile(xf86config, XF86Config)) {
 
345
        char msg[1024];
 
346
 
 
347
        XmuSnprintf(msg, sizeof(msg), "Failed to write configuration file %s.",
 
348
                   xf86config);
 
349
        ClearScreen();
 
350
        refresh();
 
351
        (void)Dialog("Write failed!", msg, 8, 60, "  Ok  ", NULL, 0);
 
352
        XtFree(xf86config);
 
353
        return (-1);
 
354
    }
 
355
    XtFree(xf86config);
 
356
 
 
357
    return (1);
 
358
}
 
359
 
 
360
static char *protocols[] = {
 
361
#ifdef __UNIXOS2__
 
362
    "OS2Mouse",
 
363
#endif
 
364
#ifdef __SCO__
 
365
    "OsMouse",
 
366
#endif
 
367
#ifdef __UNIXWARE__
 
368
    "Xqueue",
 
369
#endif
 
370
#ifdef WSCONS_SUPPORT
 
371
    "wsmouse",
 
372
#endif
 
373
    "Auto",
 
374
    "SysMouse",
 
375
    "MouseSystems",
 
376
    "BusMouse",
 
377
    "PS/2",
 
378
    "Microsoft",
 
379
#ifndef __FreeBSD__
 
380
    "ImPS/2",
 
381
    "ExplorerPS/2",
 
382
    "GlidePointPS/2",
 
383
    "MouseManPlusPS/2",
 
384
    "NetMousePS/2",
 
385
    "NetScrollPS/2",
 
386
    "ThinkingMousePS/2",
 
387
#endif
 
388
    "AceCad",
 
389
    "GlidePoint",
 
390
    "IntelliMouse",
 
391
    "Logitech",
 
392
    "MMHitTab",
 
393
    "MMSeries",
 
394
    "MouseMan",
 
395
    "ThinkingMouse",
 
396
};
 
397
 
 
398
static int
 
399
MouseConfig(void)
 
400
{
 
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;
 
406
 
 
407
    nlist = 0;
 
408
    while (input) {
 
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;
 
417
            ++nlist;
 
418
        }
 
419
        input = (XF86ConfInputPtr)(input->list.next);
 
420
    }
 
421
 
 
422
    input = NULL;
 
423
 
 
424
    if (nlist) {
 
425
        list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
 
426
        list[nlist++] = XtNewString("Add new mouse");
 
427
        if (nlist == 2) {
 
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);
 
431
            ++nlist;
 
432
        }
 
433
        else
 
434
            list[nlist++] = XtNewString("Remove mouse");
 
435
        ClearScreen();
 
436
        refresh();
 
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);
 
441
        if (i < 0) {
 
442
            for (i = 0; i < nlist; i++)
 
443
                XtFree(list[i]);
 
444
            XtFree((XtPointer)list);
 
445
            XtFree((XtPointer)inputs);
 
446
            return (-1);
 
447
        }
 
448
        if (nlist > 2 && i == nlist - 1) {
 
449
            if (nlist > 3) {
 
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);
 
454
                }
 
455
                ClearScreen();
 
456
                refresh();
 
457
                i = DialogMenu("Remove mouse",
 
458
                               "Select which mouse to remove",
 
459
                               13, 60, 4, nlist - 2, list,
 
460
                               " Remove ", " Cancel ", 0);
 
461
                if (i < 0) {
 
462
                    for (i = 0; i < nlist; i++)
 
463
                        XtFree(list[i]);
 
464
                    XtFree((XtPointer)list);
 
465
                    XtFree((XtPointer)inputs);
 
466
                    return (-1);
 
467
                }
 
468
                input = inputs[i];
 
469
            }
 
470
            else
 
471
                input = inputs[0];
 
472
            for (i = 0; i < nlist; i++)
 
473
                XtFree(list[i]);
 
474
            XtFree((XtPointer)list);
 
475
            XtFree((XtPointer)inputs);
 
476
            xf86removeInput(XF86Config, input);
 
477
            return (0);
 
478
        }
 
479
        if (i < nlist - 2)
 
480
            input = inputs[i];
 
481
    }
 
482
    for (i = 0; i < nlist; i++)
 
483
        XtFree(list[i]);
 
484
    XtFree((XtPointer)list);
 
485
    XtFree((XtPointer)inputs);
 
486
 
 
487
    if (input == NULL) {
 
488
        char label[32];
 
489
 
 
490
        input = (XF86ConfInputPtr)XtCalloc(1, sizeof(XF86ConfInputRec));
 
491
        XmuSnprintf(label, sizeof(label), "Mouse%d", nlist ? nlist - 2 : 0);
 
492
        ClearScreen();
 
493
        refresh();
 
494
        input->inp_identifier =
 
495
            DialogInput("Mouse identifier",
 
496
                        "Enter an identifier for your mouse definition:",
 
497
                        11, 40, label,
 
498
                        " Next >>", " Cancel ", 0);
 
499
        if (input->inp_identifier == NULL) {
 
500
            XtFree((XtPointer)input);
 
501
            return (-1);
 
502
        }
 
503
    }
 
504
 
 
505
    def = 0;
 
506
    option = xf86findOption(input->inp_option_lst, "Protocol");
 
507
    if (option)
 
508
        for (i = 0; i < sizeof(protocols)/sizeof(protocols[0]); i++)
 
509
            if (strcasecmp(option->opt_val, protocols[i]) == 0) {
 
510
                def = i;
 
511
                break;
 
512
            }
 
513
 
 
514
    ClearScreen();
 
515
    refresh();
 
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);
 
523
    if (i < 0) {
 
524
        if (input->inp_driver == NULL) {
 
525
            XtFree(input->inp_driver);
 
526
            XtFree((XtPointer)input);
 
527
        }
 
528
        return (i);
 
529
    }
 
530
    proto = i;
 
531
 
 
532
    def = 0;
 
533
    if (input->inp_driver) {
 
534
        option = xf86findOption(input->inp_option_lst, "Emulate3Buttons");
 
535
        def = option ? 0 : 1;
 
536
    }
 
537
    ClearScreen();
 
538
    refresh();
 
539
    i = Dialog("Mouse 3 buttons emulation",
 
540
               "If your mouse has only two buttons, it is recommended that "
 
541
               "you enable Emulate3Buttons.\n"
 
542
               "\n"
 
543
               "Do you want to enable Emulate3Buttons?",
 
544
               10, 60, " Yes ", " No ", def);
 
545
    if (i < 0)
 
546
        return (i);
 
547
    emul = !i;
 
548
 
 
549
    str = NULL;
 
550
    option = xf86findOption(input->inp_option_lst, "Device");
 
551
    if (option)
 
552
        str = option->opt_val;
 
553
    if (str == NULL)
 
554
#ifdef WSCONS_SUPPORT
 
555
        str = "/dev/wsmouse";
 
556
#elif defined(__FreeBSD__)
 
557
        str = "/dev/sysmouse";
 
558
#elif defined(__UNIXOS2__)
 
559
        str = "mouse$";
 
560
#else
 
561
        str = "/dev/mouse";
 
562
#endif
 
563
 
 
564
    ClearScreen();
 
565
    refresh();
 
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);
 
573
        }
 
574
        return (-1);
 
575
    }
 
576
 
 
577
    /* Finish mouse configuration */
 
578
    option = xf86findOption(input->inp_option_lst, "Protocol");
 
579
    if (option) {
 
580
        XtFree((XtPointer)option->opt_val);
 
581
        option->opt_val = XtNewString(protocols[proto]);
 
582
    }
 
583
    else
 
584
        input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
 
585
                XtNewString("Protocol"), XtNewString(protocols[proto]));
 
586
 
 
587
    option = xf86findOption(input->inp_option_lst, "Emulate3Buttons");
 
588
    if (option && !emul) {
 
589
        xf86removeOption(&input->inp_option_lst, "Emulate3Buttons");
 
590
    }
 
591
    else if (option == NULL && emul)
 
592
        input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
 
593
                XtNewString("Emulate3Buttons"), NULL);
 
594
 
 
595
    option = xf86findOption(input->inp_option_lst, "Device");
 
596
    if (option) {
 
597
        XtFree((XtPointer)option->opt_val);
 
598
        option->opt_val = device;
 
599
    }
 
600
    else
 
601
        input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
 
602
                XtNewString("Device"), device);
 
603
 
 
604
    if (input->inp_driver == NULL) {
 
605
        input->inp_driver = XtNewString("mouse");
 
606
        XF86Config->conf_input_lst =
 
607
            xf86addInput(XF86Config->conf_input_lst, input);
 
608
    }
 
609
 
 
610
    return (1);
 
611
}
 
612
 
 
613
static int
 
614
KeyboardConfig(void)
 
615
{
 
616
    int i;
 
617
    char *rulesfile;
 
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;
 
623
    int nlist, def;
 
624
    XF86OptionPtr option;
 
625
 
 
626
    nlist = 0;
 
627
    while (input) {
 
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;
 
636
            ++nlist;
 
637
        }
 
638
        input = (XF86ConfInputPtr)(input->list.next);
 
639
    }
 
640
 
 
641
    input = NULL;
 
642
 
 
643
    if (nlist) {
 
644
        list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
 
645
        list[nlist++] = XtNewString("Add new keyboard");
 
646
        if (nlist == 2) {
 
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);
 
650
            ++nlist;
 
651
        }
 
652
        else
 
653
            list[nlist++] = XtNewString("Remove keyboard");
 
654
        ClearScreen();
 
655
        refresh();
 
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);
 
660
        if (i < 0) {
 
661
            for (i = 0; i < nlist; i++)
 
662
                XtFree(list[i]);
 
663
            XtFree((XtPointer)list);
 
664
            XtFree((XtPointer)inputs);
 
665
            return (-1);
 
666
        }
 
667
        if (nlist > 2 && i == nlist - 1) {
 
668
            if (nlist > 3) {
 
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);
 
673
                }
 
674
                ClearScreen();
 
675
                refresh();
 
676
                i = DialogMenu("Remove keyboard",
 
677
                               "Select which keyboard to remove",
 
678
                               13, 60, 4, nlist - 2, list,
 
679
                               " Remove ", " Cancel ", 0);
 
680
                if (i < 0) {
 
681
                    for (i = 0; i < nlist; i++)
 
682
                        XtFree(list[i]);
 
683
                    XtFree((XtPointer)list);
 
684
                    XtFree((XtPointer)inputs);
 
685
                    return (-1);
 
686
                }
 
687
                input = inputs[i];
 
688
            }
 
689
            else
 
690
                input = inputs[0];
 
691
            for (i = 0; i < nlist; i++)
 
692
                XtFree(list[i]);
 
693
            XtFree((XtPointer)list);
 
694
            XtFree((XtPointer)inputs);
 
695
            xf86removeInput(XF86Config, input);
 
696
            return (0);
 
697
        }
 
698
        if (i < nlist - 2)
 
699
            input = inputs[i];
 
700
    }
 
701
    for (i = 0; i < nlist; i++)
 
702
        XtFree(list[i]);
 
703
    XtFree((XtPointer)list);
 
704
    XtFree((XtPointer)inputs);
 
705
 
 
706
    if (input == NULL) {
 
707
        char label[32];
 
708
 
 
709
        input = (XF86ConfInputPtr)XtCalloc(1, sizeof(XF86ConfInputRec));
 
710
        XmuSnprintf(label, sizeof(label), "Keyboard%d", nlist ? nlist - 2 : 0);
 
711
        ClearScreen();
 
712
        refresh();
 
713
        input->inp_identifier =
 
714
            DialogInput("Keyboard identifier",
 
715
                        "Enter an identifier for your keyboard definition:",
 
716
                        11, 40, label,
 
717
                        " Next >>", " Cancel ", 0);
 
718
        if (input->inp_identifier == NULL) {
 
719
            XtFree((XtPointer)input);
 
720
            return (-1);
 
721
        }
 
722
    }
 
723
 
 
724
    if (first) {
 
725
        first = 0;
 
726
#ifdef XFREE98_XKB
 
727
        rulesfile = XKB_RULES_DIR "/xfree98";
 
728
#else
 
729
        rulesfile = XKB_RULES_DIR "/"__XKBDEFRULES__;
 
730
#endif
 
731
        rules = XkbRF_Load(rulesfile, "", True, False);
 
732
        if (rules == NULL) {
 
733
            ClearScreen();
 
734
            refresh();
 
735
            Dialog("Configuration error",
 
736
                   "XKB rules file not found.\n"
 
737
                   "\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");
 
749
#else
 
750
                input->inp_driver = XtNewString("kbd");
 
751
#endif
 
752
                XF86Config->conf_input_lst =
 
753
                    xf86addInput(XF86Config, input);
 
754
            }
 
755
            return (0);
 
756
        }
 
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);
 
763
    }
 
764
    else if (rules == NULL)
 
765
        return (-1);
 
766
 
 
767
    def = 0;
 
768
    option = xf86findOption(input->inp_option_lst, "XkbModel");
 
769
    if (option) {
 
770
        for (i = 0; i < rules->models.num_desc; i++)
 
771
            if (strcasecmp(option->opt_val, rules->models.desc[i].name) == 0) {
 
772
                def = i;
 
773
                break;
 
774
            }
 
775
    }
 
776
    ClearScreen();
 
777
    refresh();
 
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);
 
784
    if (i < 0)
 
785
        return (i);
 
786
    model = rules->models.desc[i].name;
 
787
 
 
788
    def = 0;
 
789
    option = xf86findOption(input->inp_option_lst, "XkbLayout");
 
790
    if (option) {
 
791
        for (i = 0; i < rules->layouts.num_desc; i++)
 
792
            if (strcasecmp(option->opt_val, rules->layouts.desc[i].name) == 0) {
 
793
                def = i;
 
794
                break;
 
795
            }
 
796
    }
 
797
    ClearScreen();
 
798
    refresh();
 
799
    i = DialogMenu("Keyboard layout",
 
800
                   "Select keyboard layout:",
 
801
                   20, 60, 11, rules->layouts.num_desc,
 
802
                   layouts, " Finish ", " Cancel ", def);
 
803
    if (i < 0)
 
804
        return (i);
 
805
    layout = rules->layouts.desc[i].name;
 
806
 
 
807
    /* Finish keyboard configuration */
 
808
    option = xf86findOption(input->inp_option_lst, "XkbModel");
 
809
    if (option) {
 
810
        XtFree((XtPointer)option->opt_val);
 
811
        option->opt_val = XtNewString(model);
 
812
    }
 
813
    else
 
814
        input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
 
815
                XtNewString("XkbModel"), XtNewString(model));
 
816
 
 
817
    option = xf86findOption(input->inp_option_lst, "XkbLayout");
 
818
    if (option) {
 
819
        XtFree((XtPointer)option->opt_val);
 
820
        option->opt_val = XtNewString(layout);
 
821
    }
 
822
    else
 
823
        input->inp_option_lst = xf86addNewOption(input->inp_option_lst,
 
824
                XtNewString("XkbLayout"), XtNewString(layout));
 
825
 
 
826
    if (input->inp_driver == NULL) {
 
827
#if defined(USE_DEPRECATED_KEYBOARD_DRIVER)
 
828
        input->inp_driver = XtNewString("keyboard");
 
829
#else
 
830
        input->inp_driver = XtNewString("kbd");
 
831
#endif
 
832
        XF86Config->conf_input_lst =
 
833
            xf86addInput(XF86Config->conf_input_lst, input);
 
834
    }
 
835
 
 
836
    return (1);
 
837
}
 
838
 
 
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"
 
856
};
 
857
 
 
858
static char *vrefresh[] = {
 
859
#define CONF_MONITOR_VREFRESH   0
 
860
    "Enter your own vertical sync range",
 
861
    "50 - 70",
 
862
    "50 - 90",
 
863
    "50 - 100",
 
864
    "40 - 150",
 
865
};
 
866
 
 
867
static int
 
868
MonitorConfig(void)
 
869
{
 
870
    int i;
 
871
    XF86ConfMonitorPtr *monitors = NULL, monitor = XF86Config->conf_monitor_lst;
 
872
    char **list = NULL, *identifier = NULL, *tmp;
 
873
    int nlist, def;
 
874
    char hsync_str[256], vrefresh_str[256];
 
875
 
 
876
    hsync_str[0] = vrefresh_str[0] = '\0';
 
877
    nlist = 0;
 
878
    while (monitor) {
 
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;
 
886
        ++nlist;
 
887
        monitor = (XF86ConfMonitorPtr)(monitor->list.next);
 
888
    }
 
889
 
 
890
    monitor = NULL;
 
891
 
 
892
    if (nlist) {
 
893
        list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
 
894
        list[nlist++] = XtNewString("Add new monitor");
 
895
        if (nlist == 2) {
 
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);
 
899
            ++nlist;
 
900
        }
 
901
        else
 
902
            list[nlist++] = XtNewString("Remove monitor");
 
903
        ClearScreen();
 
904
        refresh();
 
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);
 
909
        if (i < 0) {
 
910
            for (i = 0; i < nlist; i++)
 
911
                XtFree(list[i]);
 
912
            XtFree((XtPointer)list);
 
913
            XtFree((XtPointer)monitors);
 
914
            return (-1);
 
915
        }
 
916
        if (nlist > 2 && i == nlist - 1) {
 
917
            if (nlist > 3) {
 
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);
 
922
                }
 
923
                ClearScreen();
 
924
                refresh();
 
925
                i = DialogMenu("Remove monitor",
 
926
                               "Select which monitor to remove",
 
927
                               13, 60, 4, nlist - 2, list,
 
928
                               " Remove ", " Cancel ", 0);
 
929
                if (i < 0) {
 
930
                    for (i = 0; i < nlist; i++)
 
931
                        XtFree(list[i]);
 
932
                    XtFree((XtPointer)list);
 
933
                    XtFree((XtPointer)monitors);
 
934
                    return (-1);
 
935
                }
 
936
                monitor = monitors[i];
 
937
            }
 
938
            else
 
939
                monitor = monitors[0];
 
940
            for (i = 0; i < nlist; i++)
 
941
                XtFree(list[i]);
 
942
            XtFree((XtPointer)list);
 
943
            XtFree((XtPointer)monitors);
 
944
            xf86removeMonitor(XF86Config, monitor);
 
945
            return (0);
 
946
        }
 
947
        if (i < nlist - 2)
 
948
            monitor = monitors[i];
 
949
    }
 
950
    for (i = 0; i < nlist; i++)
 
951
        XtFree(list[i]);
 
952
    XtFree((XtPointer)list);
 
953
    XtFree((XtPointer)monitors);
 
954
 
 
955
    if (monitor == NULL) {
 
956
        char label[32];
 
957
 
 
958
        monitor = (XF86ConfMonitorPtr)XtCalloc(1, sizeof(XF86ConfMonitorRec));
 
959
        XmuSnprintf(label, sizeof(label), "Monitor%d", nlist ? nlist - 2 : 0);
 
960
        ClearScreen();
 
961
        refresh();
 
962
        identifier =
 
963
            DialogInput("Monitor identifier",
 
964
                        "Enter an identifier for your monitor definition:",
 
965
                        11, 40, label,
 
966
                        " Next >>", " Cancel ", 0);
 
967
        if (identifier == NULL) {
 
968
            XtFree((XtPointer)monitor);
 
969
            return (-1);
 
970
        }
 
971
    }
 
972
 
 
973
    if (monitor->mon_identifier == NULL) {
 
974
        ClearScreen();
 
975
        refresh();
 
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"
 
982
                   "\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);
 
986
        if (i != 0) {
 
987
            XtFree(identifier);
 
988
            XtFree((XtPointer)monitor);
 
989
            return (-1);
 
990
        }
 
991
    }
 
992
 
 
993
    def = 0;
 
994
    if (monitor->mon_identifier) {
 
995
        int len;
 
996
 
 
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) {
 
1003
                def = i;
 
1004
                break;
 
1005
            }
 
1006
        }
 
1007
    }
 
1008
    if (hsync_str[0] == '\0')
 
1009
        strcpy(hsync_str, "31.5");
 
1010
 
 
1011
    ClearScreen();
 
1012
    refresh();
 
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);
 
1020
    if (i < 0) {
 
1021
        if (monitor->mon_identifier == NULL) {
 
1022
            XtFree(identifier);
 
1023
            XtFree((XtPointer)monitor);
 
1024
        }
 
1025
        return (-1);
 
1026
    }
 
1027
    if (i == CONF_MONITOR_HSYNC) {
 
1028
        ClearScreen();
 
1029
        refresh();
 
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"
 
1036
                          "\n"
 
1037
                          "Horizontal sync range:", 16, 62, hsync_str,
 
1038
                          "  Ok  ", " Cancel ", def);
 
1039
        if (tmp == NULL) {
 
1040
            if (monitor->mon_identifier == NULL) {
 
1041
                XtFree(identifier);
 
1042
                XtFree((XtPointer)monitor);
 
1043
            }
 
1044
            return (-1);
 
1045
        }
 
1046
        XmuSnprintf(hsync_str, sizeof(hsync_str), "%s", tmp);
 
1047
        XtFree(tmp);
 
1048
    }
 
1049
    else {
 
1050
        tmp = strchr(hsync[i], ';');
 
1051
        strncpy(hsync_str, hsync[i], tmp - hsync[i]);
 
1052
        hsync_str[tmp - hsync[i]] = '\0';
 
1053
    }
 
1054
 
 
1055
    def = 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) {
 
1061
                def = i;
 
1062
                break;
 
1063
            }
 
1064
        }
 
1065
    }
 
1066
    if (vrefresh_str[0] == '\0')
 
1067
        strcpy(vrefresh_str, "50 - 70");
 
1068
    ClearScreen();
 
1069
    refresh();
 
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);
 
1078
    if (i < 0) {
 
1079
        if (monitor->mon_identifier == NULL) {
 
1080
            XtFree(identifier);
 
1081
            XtFree((XtPointer)monitor);
 
1082
        }
 
1083
        return (i);
 
1084
    }
 
1085
    if (i == CONF_MONITOR_VREFRESH) {
 
1086
        ClearScreen();
 
1087
        refresh();
 
1088
        tmp = DialogInput("Monitor VertRefresh",
 
1089
                          "Vertical sync range:", 10, 50, vrefresh_str,
 
1090
                          " Done ", " Cancel ", 0);
 
1091
        if (tmp == NULL) {
 
1092
            if (monitor->mon_identifier == NULL) {
 
1093
                XtFree(identifier);
 
1094
                XtFree((XtPointer)monitor);
 
1095
            }
 
1096
            return (-1);
 
1097
        }
 
1098
        XmuSnprintf(vrefresh_str, sizeof(vrefresh_str), "%s", tmp);
 
1099
        XtFree(tmp);
 
1100
    }
 
1101
    else
 
1102
        strcpy(vrefresh_str, vrefresh[i]);
 
1103
 
 
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);
 
1113
    }
 
1114
 
 
1115
    return (1);
 
1116
}
 
1117
 
 
1118
static int
 
1119
CardConfig(void)
 
1120
{
 
1121
    int i;
 
1122
    XF86ConfDevicePtr *devices = NULL, device = XF86Config->conf_device_lst;
 
1123
    char **list = NULL, *identifier = NULL, *driver, *busid, *tmp;
 
1124
    int nlist, def;
 
1125
    CardsEntry *entry = NULL;
 
1126
    static char **drivers;
 
1127
    static int ndrivers;
 
1128
    static char *xdrivers[] = {
 
1129
        "apm",
 
1130
        "ark",
 
1131
        "ati",
 
1132
        "r128",
 
1133
        "radeon",
 
1134
        "chips",
 
1135
        "cirrus",
 
1136
        "cyrix",
 
1137
        "fbdev",
 
1138
        "glint",
 
1139
        "i128",
 
1140
        "i740",
 
1141
        "i810",
 
1142
        "imstt",
 
1143
        "mga",
 
1144
        "neomagic",
 
1145
        "nv",
 
1146
        "rendition",
 
1147
        "s3",
 
1148
        "s3virge",
 
1149
        "savage",
 
1150
        "siliconmotion",
 
1151
        "sis",
 
1152
        "tdfx",
 
1153
        "tga",
 
1154
        "trident",
 
1155
        "tseng",
 
1156
        "vmware",
 
1157
        "vga",
 
1158
        "vesa",
 
1159
    };
 
1160
 
 
1161
#ifdef USE_MODULES
 
1162
    if (!nomodules) {
 
1163
        xf86cfgModuleOptions *opts = module_options;
 
1164
 
 
1165
        drivers = NULL;
 
1166
        ndrivers = 0;
 
1167
        while (opts) {
 
1168
            if (opts->type == VideoModule) {
 
1169
                ++ndrivers;
 
1170
                drivers = (char**)XtRealloc((XtPointer)drivers,
 
1171
                                            ndrivers * sizeof(char*));
 
1172
                /* XXX no private copy */
 
1173
                drivers[ndrivers - 1] = opts->name;
 
1174
            }
 
1175
            opts = opts->next;
 
1176
        }
 
1177
    }
 
1178
    else
 
1179
#endif
 
1180
    {
 
1181
        ndrivers = sizeof(xdrivers) / sizeof(xdrivers[0]);
 
1182
        drivers = xdrivers;
 
1183
    }
 
1184
 
 
1185
    nlist = 0;
 
1186
    while (device) {
 
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;
 
1194
        ++nlist;
 
1195
        device = (XF86ConfDevicePtr)(device->list.next);
 
1196
    }
 
1197
 
 
1198
    device = NULL;
 
1199
 
 
1200
    if (nlist) {
 
1201
        list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
 
1202
        list[nlist++] = XtNewString("Add new card");
 
1203
        if (nlist == 2) {
 
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);
 
1207
            ++nlist;
 
1208
        }
 
1209
        else
 
1210
            list[nlist++] = XtNewString("Remove device");
 
1211
        ClearScreen();
 
1212
        refresh();
 
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);
 
1217
        if (i < 0) {
 
1218
            for (i = 0; i < nlist; i++)
 
1219
                XtFree(list[i]);
 
1220
            XtFree((XtPointer)list);
 
1221
            XtFree((XtPointer)devices);
 
1222
            return (-1);
 
1223
        }
 
1224
        if (nlist > 2 && i == nlist - 1) {
 
1225
            if (nlist > 3) {
 
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);
 
1230
                }
 
1231
                ClearScreen();
 
1232
                refresh();
 
1233
                i = DialogMenu("Remove card",
 
1234
                               "Select which card to remove",
 
1235
                               13, 60, 4, nlist - 2, list,
 
1236
                               " Remove ", " Cancel ", 0);
 
1237
                if (i < 0) {
 
1238
                    for (i = 0; i < nlist; i++)
 
1239
                        XtFree(list[i]);
 
1240
                    XtFree((XtPointer)list);
 
1241
                    XtFree((XtPointer)devices);
 
1242
                    return (-1);
 
1243
                }
 
1244
                device = devices[i];
 
1245
            }
 
1246
            else
 
1247
                device = devices[0];
 
1248
            for (i = 0; i < nlist; i++)
 
1249
                XtFree(list[i]);
 
1250
            XtFree((XtPointer)list);
 
1251
            XtFree((XtPointer)devices);
 
1252
            xf86removeDevice(XF86Config, device);
 
1253
            return (0);
 
1254
        }
 
1255
        if (i < nlist - 2)
 
1256
            device = devices[i];
 
1257
    }
 
1258
    for (i = 0; i < nlist; i++)
 
1259
        XtFree(list[i]);
 
1260
    XtFree((XtPointer)list);
 
1261
    XtFree((XtPointer)devices);
 
1262
 
 
1263
    if (device == NULL) {
 
1264
        char label[32];
 
1265
 
 
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);
 
1269
        ClearScreen();
 
1270
        refresh();
 
1271
        identifier =
 
1272
            DialogInput("Card identifier",
 
1273
                        "Enter an identifier for your card definition:",
 
1274
                        11, 40, label,
 
1275
                        " Next >>", " Cancel ", 0);
 
1276
        if (identifier == NULL) {
 
1277
            XtFree((XtPointer)device);
 
1278
            return (-1);
 
1279
        }
 
1280
    }
 
1281
 
 
1282
    ClearScreen();
 
1283
    refresh();
 
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"
 
1288
               "\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"
 
1294
               "\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;
 
1298
        static int ncards;
 
1299
 
 
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 **";
 
1308
            ++ncards;
 
1309
        }
 
1310
        if (device->dev_card)
 
1311
            entry = LookupCard(device->dev_card);
 
1312
        def = 0;
 
1313
        if (entry) {
 
1314
            for (i = 0; i < NumCardsEntry; i++)
 
1315
                if (strcasecmp(CardsDB[i]->name, entry->name) == 0) {
 
1316
                    def = i + 1;
 
1317
                    break;
 
1318
                }
 
1319
            /* make sure entry is set to null again */
 
1320
            entry = NULL;
 
1321
        }
 
1322
 
 
1323
        i = DialogMenu("Card database",
 
1324
                       "Select name that better matches your card:",
 
1325
                       20, 70, 11, ncards, cards, "Next >>", " Cancel ", def);
 
1326
        if (i > 0)
 
1327
            entry = LookupCard(cards[i]);
 
1328
    }
 
1329
 
 
1330
    def = 0;
 
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) {
 
1335
            def = i;
 
1336
            break;
 
1337
        }
 
1338
 
 
1339
    ClearScreen();
 
1340
    refresh();
 
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);
 
1345
    if (i < 0) {
 
1346
        if (device->dev_identifier == NULL) {
 
1347
            XtFree(identifier);
 
1348
            XtFree((XtPointer)device);
 
1349
        }
 
1350
        return (-1);
 
1351
    }
 
1352
    driver = ndrivers ? drivers[i] : "vga";
 
1353
 
 
1354
    ClearScreen();
 
1355
    refresh();
 
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);
 
1361
 
 
1362
    /* Finish card configuration */
 
1363
    if (entry) {
 
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);
 
1369
        }
 
1370
        if (entry->ramdac) {
 
1371
            XtFree(device->dev_ramdac);
 
1372
            device->dev_ramdac = XtNewString(entry->ramdac);
 
1373
        }
 
1374
        if (entry->clockchip) {
 
1375
            XtFree(entry->clockchip);
 
1376
            device->dev_clockchip = XtNewString(entry->clockchip);
 
1377
        }
 
1378
    }
 
1379
    if (busid) {
 
1380
        XtFree(device->dev_busid);
 
1381
        if (*busid)
 
1382
            device->dev_busid = busid;
 
1383
        else {
 
1384
            device->dev_busid = NULL;
 
1385
            XtFree(busid);
 
1386
        }
 
1387
    }
 
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);
 
1394
    }
 
1395
 
 
1396
    return (1);
 
1397
}
 
1398
 
 
1399
static char *depths[] = {
 
1400
    "1 bit, monochrome",
 
1401
    "4 bit, 16 colors",
 
1402
    "8 bit, 256 colors",
 
1403
    "15 bits, 32Kb colors",
 
1404
    "16 bits, 65Kb colors",
 
1405
    "24 bits, 16Mb colors",
 
1406
};
 
1407
 
 
1408
static char *modes[] = {
 
1409
    "2048x1536",
 
1410
    "1920x1440",
 
1411
    "1800x1400",
 
1412
    "1600x1200",
 
1413
    "1400x1050",
 
1414
    "1280x1024",
 
1415
    "1280x960",
 
1416
    "1152x864",
 
1417
    "1024x768",
 
1418
    "800x600",
 
1419
    "640x480",
 
1420
    "640x400",
 
1421
    "512x384",
 
1422
    "400x300",
 
1423
    "320x240",
 
1424
    "320x200",
 
1425
};
 
1426
 
 
1427
static int
 
1428
ScreenConfig(void)
 
1429
{
 
1430
    int i, disp_allocated;
 
1431
    XF86ConfScreenPtr *screens = NULL, screen = XF86Config->conf_screen_lst;
 
1432
    char **list = NULL, *identifier = NULL;
 
1433
    int nlist, def;
 
1434
    XF86ConfDevicePtr device = NULL;
 
1435
    XF86ConfMonitorPtr monitor = NULL;
 
1436
    XF86ConfDisplayPtr display;
 
1437
    XF86ModePtr mode, ptr = NULL;
 
1438
    char *checks;
 
1439
 
 
1440
    nlist = 0;
 
1441
    while (screen) {
 
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;
 
1449
        ++nlist;
 
1450
        screen = (XF86ConfScreenPtr)(screen->list.next);
 
1451
    }
 
1452
 
 
1453
    screen = NULL;
 
1454
 
 
1455
    if (nlist) {
 
1456
        list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
 
1457
        list[nlist++] = XtNewString("Add new screen");
 
1458
        if (nlist == 2) {
 
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);
 
1462
            ++nlist;
 
1463
        }
 
1464
        else
 
1465
            list[nlist++] = XtNewString("Remove screen");
 
1466
        ClearScreen();
 
1467
        refresh();
 
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);
 
1472
        if (i < 0) {
 
1473
            for (i = 0; i < nlist; i++)
 
1474
                XtFree(list[i]);
 
1475
            XtFree((XtPointer)list);
 
1476
            XtFree((XtPointer)screens);
 
1477
            return (-1);
 
1478
        }
 
1479
        if (nlist > 2 && i == nlist - 1) {
 
1480
            if (nlist > 3) {
 
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);
 
1485
                }
 
1486
                ClearScreen();
 
1487
                refresh();
 
1488
                i = DialogMenu("Remove screen",
 
1489
                               "Select which screen to remove",
 
1490
                               13, 60, 4, nlist - 2, list,
 
1491
                               " Remove ", " Cancel ", 0);
 
1492
                if (i < 0) {
 
1493
                    for (i = 0; i < nlist; i++)
 
1494
                        XtFree(list[i]);
 
1495
                    XtFree((XtPointer)list);
 
1496
                    XtFree((XtPointer)screens);
 
1497
                    return (-1);
 
1498
                }
 
1499
                screen = screens[i];
 
1500
            }
 
1501
            else
 
1502
                screen = screens[0];
 
1503
            for (i = 0; i < nlist; i++)
 
1504
                XtFree(list[i]);
 
1505
            XtFree((XtPointer)list);
 
1506
            XtFree((XtPointer)screens);
 
1507
            xf86removeScreen(XF86Config, screen);
 
1508
            return (0);
 
1509
        }
 
1510
        if (i < nlist - 2)
 
1511
            screen = screens[i];
 
1512
    }
 
1513
    for (i = 0; i < nlist; i++)
 
1514
        XtFree(list[i]);
 
1515
    XtFree((XtPointer)list);
 
1516
    XtFree((XtPointer)screens);
 
1517
 
 
1518
    if (screen == NULL) {
 
1519
        char label[256];
 
1520
        XF86ConfDevicePtr *devices = NULL;
 
1521
        XF86ConfMonitorPtr *monitors = NULL;
 
1522
 
 
1523
        device = XF86Config->conf_device_lst;
 
1524
        monitor = XF86Config->conf_monitor_lst;
 
1525
 
 
1526
        if (device == NULL || monitor == NULL) {
 
1527
                ClearScreen();
 
1528
                refresh();
 
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);
 
1533
 
 
1534
                return (-1);
 
1535
        }
 
1536
 
 
1537
        XmuSnprintf(label, sizeof(label), "Screen%d", nlist ? nlist - 2 : 0);
 
1538
        ClearScreen();
 
1539
        refresh();
 
1540
        identifier =
 
1541
            DialogInput("Screen identifier",
 
1542
                        "Enter an identifier for your screen definition:",
 
1543
                        11, 40, label,
 
1544
                        " Next >>", " Cancel ", 0);
 
1545
        if (identifier == NULL)
 
1546
            return (-1);
 
1547
 
 
1548
        nlist = 0;
 
1549
        list = NULL;
 
1550
        while (device) {
 
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;
 
1556
            ++nlist;
 
1557
            device = (XF86ConfDevicePtr)(device->list.next);
 
1558
        }
 
1559
        ClearScreen();
 
1560
        refresh();
 
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++)
 
1564
            XtFree(list[def]);
 
1565
        XtFree((XtPointer)list);
 
1566
        if (i < 0) {
 
1567
            XtFree(identifier);
 
1568
            XtFree((XtPointer)devices);
 
1569
            return (-1);
 
1570
        }
 
1571
        device = devices[i];
 
1572
        XtFree((XtPointer)devices);
 
1573
 
 
1574
        nlist = 0;
 
1575
        list = NULL;
 
1576
        while (monitor) {
 
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;
 
1582
            ++nlist;
 
1583
            monitor = (XF86ConfMonitorPtr)(monitor->list.next);
 
1584
        }
 
1585
        XmuSnprintf(label, sizeof(label),
 
1586
                    "Select the monitor connected to \"%s\":",
 
1587
                    device->dev_identifier);
 
1588
        ClearScreen();
 
1589
        refresh();
 
1590
        i = DialogMenu("Screen monitor", label,
 
1591
                       13, 60, 4, nlist, list, " Next >>", " Cancel ", 0);
 
1592
        for (def = 0; def < nlist; def++)
 
1593
            XtFree(list[def]);
 
1594
        XtFree((XtPointer)list);
 
1595
        if (i < 0) {
 
1596
            XtFree(identifier);
 
1597
            XtFree((XtPointer)monitors);
 
1598
            return (-1);
 
1599
        }
 
1600
        monitor = monitors[i];
 
1601
        XtFree((XtPointer)monitors);
 
1602
 
 
1603
        screen = (XF86ConfScreenPtr)XtCalloc(1, sizeof(XF86ConfScreenRec));
 
1604
        screen->scrn_device = device;
 
1605
        screen->scrn_monitor = monitor;
 
1606
    }
 
1607
 
 
1608
    if (screen->scrn_defaultdepth == 1)
 
1609
        def = 0;
 
1610
    else if (screen->scrn_defaultdepth == 4)
 
1611
        def = 1;
 
1612
    else if (screen->scrn_defaultdepth == 8)
 
1613
        def = 2;
 
1614
    else if (screen->scrn_defaultdepth == 15)
 
1615
        def = 3;
 
1616
    else if (screen->scrn_defaultdepth == 16)
 
1617
        def = 4;
 
1618
    else if (screen->scrn_defaultdepth == 24)
 
1619
        def = 5;
 
1620
    else {
 
1621
        if (screen->scrn_device && screen->scrn_device->dev_driver &&
 
1622
            strcmp(screen->scrn_device->dev_driver, "vga") == 0)
 
1623
            def = 1;            /* 4bpp */
 
1624
        else
 
1625
            def = 2;            /* 8bpp */
 
1626
    }
 
1627
    ClearScreen();
 
1628
    refresh();
 
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);
 
1633
    if (i < 0) {
 
1634
        if (screen->scrn_identifier == NULL) {
 
1635
            XtFree(identifier);
 
1636
            XtFree((XtPointer)screen);
 
1637
        }
 
1638
        return (-1);
 
1639
    }
 
1640
    else
 
1641
        /* XXX depths must begin with the depth number */
 
1642
        screen->scrn_defaultdepth = atoi(depths[i]);
 
1643
 
 
1644
    def = 0;    /* use def to count how many modes are selected*/
 
1645
    nlist = 0;
 
1646
    list = NULL;
 
1647
    checks = XtMalloc(sizeof(modes) / sizeof(modes[0]));
 
1648
    /* XXX list fields in the code below are not allocated */
 
1649
    disp_allocated = 0;
 
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;
 
1657
        disp_allocated = 1;
 
1658
    }
 
1659
    else {
 
1660
        mode = display->disp_mode_lst;
 
1661
        while (mode) {
 
1662
            for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++)
 
1663
                if (strcmp(modes[i], mode->mode_name) == 0) {
 
1664
                    break;
 
1665
                }
 
1666
 
 
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]) +
 
1672
                                   nlist + 1);
 
1673
                checks[nlist] = 1;
 
1674
                ++def;
 
1675
                nlist++;
 
1676
                break;
 
1677
            }
 
1678
            mode = (XF86ModePtr)(mode->list.next);
 
1679
        }
 
1680
    }
 
1681
 
 
1682
    for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++)
 
1683
        checks[i + nlist] = 0;
 
1684
 
 
1685
    mode = display->disp_mode_lst;
 
1686
    while (mode) {
 
1687
        for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++)
 
1688
            if (strcmp(modes[i], mode->mode_name) == 0) {
 
1689
                ++def;
 
1690
                checks[i + nlist] = 1;
 
1691
                break;
 
1692
        }
 
1693
        mode = (XF86ModePtr)(mode->list.next);
 
1694
    }
 
1695
 
 
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]);
 
1703
 
 
1704
    ClearScreen();
 
1705
    refresh();
 
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);
 
1710
    if (i < 0) {
 
1711
        if (screen->scrn_identifier == NULL) {
 
1712
            XtFree(identifier);
 
1713
            XtFree((XtPointer)screen);
 
1714
            XtFree((XtPointer)list);
 
1715
            if (disp_allocated)
 
1716
                XtFree((XtPointer)display);
 
1717
        }
 
1718
        return (-1);
 
1719
    }
 
1720
 
 
1721
    mode = display->disp_mode_lst;
 
1722
    while (mode) {
 
1723
        ptr = (XF86ModePtr)(mode->list.next);
 
1724
        XtFree(mode->mode_name);
 
1725
        XtFree((XtPointer)mode);
 
1726
        mode = ptr;
 
1727
    }
 
1728
    display->disp_mode_lst = NULL;
 
1729
 
 
1730
    for (i = 0; i < nlist; i++) {
 
1731
        if (checks[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;
 
1736
            else {
 
1737
                ptr->list.next = mode;
 
1738
                ptr = mode;
 
1739
            }
 
1740
        }
 
1741
    }
 
1742
    XtFree((XtPointer)list);
 
1743
 
 
1744
    if (disp_allocated) {
 
1745
        display->list.next = NULL;
 
1746
        if (screen->scrn_display_lst == NULL)
 
1747
            screen->scrn_display_lst = display;
 
1748
        else
 
1749
            screen->scrn_display_lst->list.next = display;
 
1750
    }
 
1751
 
 
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);
 
1758
    }
 
1759
 
 
1760
    return (1);
 
1761
}
 
1762
 
 
1763
static XF86ConfAdjacencyPtr
 
1764
CopyAdjacency(XF86ConfAdjacencyPtr ptr)
 
1765
{
 
1766
    XF86ConfAdjacencyPtr adj = (XF86ConfAdjacencyPtr)
 
1767
        XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
 
1768
 
 
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);
 
1789
 
 
1790
    return (adj);
 
1791
}
 
1792
 
 
1793
static XF86ConfInactivePtr
 
1794
CopyInactive(XF86ConfInactivePtr ptr)
 
1795
{
 
1796
    XF86ConfInactivePtr inac = (XF86ConfInactivePtr)
 
1797
        XtCalloc(1, sizeof(XF86ConfInactiveRec));
 
1798
 
 
1799
    inac->inactive_device = ptr->inactive_device;
 
1800
    if (ptr->inactive_device_str)
 
1801
        inac->inactive_device_str = XtNewString(ptr->inactive_device_str);
 
1802
 
 
1803
    return (inac);
 
1804
}
 
1805
 
 
1806
static XF86ConfInputrefPtr
 
1807
CopyInputref(XF86ConfInputrefPtr ptr)
 
1808
{
 
1809
    XF86ConfInputrefPtr iref = (XF86ConfInputrefPtr)
 
1810
        XtCalloc(1, sizeof(XF86ConfInputrefRec));
 
1811
    XF86OptionPtr opt = ptr->iref_option_lst;
 
1812
 
 
1813
    iref->iref_inputdev = ptr->iref_inputdev;
 
1814
    if (ptr->iref_inputdev_str)
 
1815
        iref->iref_inputdev_str = XtNewString(ptr->iref_inputdev_str);
 
1816
    while (opt) {
 
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);
 
1821
    }
 
1822
 
 
1823
    return (iref);
 
1824
}
 
1825
 
 
1826
static XF86ConfLayoutPtr
 
1827
CopyLayout(XF86ConfLayoutPtr ptr)
 
1828
{
 
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;
 
1835
 
 
1836
    if (ptr->lay_identifier)
 
1837
        lay->lay_identifier = XtNewString(ptr->lay_identifier);
 
1838
    if (adj) {
 
1839
        padj = lay->lay_adjacency_lst = CopyAdjacency(adj);
 
1840
        adj = (XF86ConfAdjacencyPtr)(adj->list.next);
 
1841
        while (adj) {
 
1842
            padj->list.next = CopyAdjacency(adj);
 
1843
            padj = (XF86ConfAdjacencyPtr)(padj->list.next);
 
1844
            adj = (XF86ConfAdjacencyPtr)(adj->list.next);
 
1845
        }
 
1846
    }
 
1847
    if (inac) {
 
1848
        pinac = lay->lay_inactive_lst = CopyInactive(inac);
 
1849
        inac = (XF86ConfInactivePtr)(inac->list.next);
 
1850
        while (inac) {
 
1851
            pinac->list.next = CopyInactive(inac);
 
1852
            pinac = (XF86ConfInactivePtr)(pinac->list.next);
 
1853
            inac = (XF86ConfInactivePtr)(inac->list.next);
 
1854
        }
 
1855
    }
 
1856
    if (iref) {
 
1857
        piref = lay->lay_input_lst = CopyInputref(iref);
 
1858
        iref = (XF86ConfInputrefPtr)(iref->list.next);
 
1859
        while (iref) {
 
1860
            piref->list.next = CopyInputref(iref);
 
1861
            piref = (XF86ConfInputrefPtr)(piref->list.next);
 
1862
            iref = (XF86ConfInputrefPtr)(iref->list.next);
 
1863
        }
 
1864
    }
 
1865
 
 
1866
    while (opt) {
 
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);
 
1871
    }
 
1872
 
 
1873
    return (lay);
 
1874
}
 
1875
 
 
1876
static void
 
1877
FreeLayout(XF86ConfLayoutPtr lay)
 
1878
{
 
1879
    static XF86ConfigRec xf86config;
 
1880
 
 
1881
    xf86config.conf_layout_lst = lay;
 
1882
    xf86removeLayout(&xf86config, lay);
 
1883
}
 
1884
 
 
1885
static int
 
1886
LayoutConfig(void)
 
1887
{
 
1888
    int i;
 
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;
 
1897
    int nlist;
 
1898
    XF86OptionPtr option;
 
1899
    XF86ConfScreenPtr screen, *screens;
 
1900
 
 
1901
    nmouses = nkeyboards = 0;
 
1902
    while (input) {
 
1903
        if (strcmp(input->inp_driver, "mouse") == 0) {
 
1904
            mouses = (XF86ConfInputPtr*)XtRealloc((XtPointer)mouses,
 
1905
                        (nmouses + 1) * sizeof(XF86ConfInputPtr));
 
1906
            mouses[nmouses] = input;
 
1907
            ++nmouses;
 
1908
        }
 
1909
        else if (IS_KBDDRIV(input->inp_driver)) {
 
1910
            keyboards = (XF86ConfInputPtr*)XtRealloc((XtPointer)keyboards,
 
1911
                            (nkeyboards + 1) * sizeof(XF86ConfInputPtr));
 
1912
            keyboards[nkeyboards] = input;
 
1913
            ++nkeyboards;
 
1914
        }
 
1915
        input = (XF86ConfInputPtr)(input->list.next);
 
1916
    }
 
1917
    if (XF86Config->conf_screen_lst == NULL ||
 
1918
        nmouses == 0 || nkeyboards == 0) {
 
1919
        XtFree((XtPointer)mouses);
 
1920
        XtFree((XtPointer)keyboards);
 
1921
        ClearScreen();
 
1922
        refresh();
 
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);
 
1927
        return (-1);
 
1928
    }
 
1929
 
 
1930
    nlist = 0;
 
1931
    while (layout) {
 
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;
 
1939
        ++nlist;
 
1940
        layout = (XF86ConfLayoutPtr)(layout->list.next);
 
1941
    }
 
1942
 
 
1943
    layout = NULL;
 
1944
 
 
1945
    if (nlist) {
 
1946
        list = (char**)XtRealloc((XtPointer)list, (nlist + 2) * sizeof(char*));
 
1947
        list[nlist++] = XtNewString("Add new layout");
 
1948
        if (nlist == 2) {
 
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);
 
1952
            ++nlist;
 
1953
        }
 
1954
        else
 
1955
            list[nlist++] = XtNewString("Remove layout");
 
1956
        ClearScreen();
 
1957
        refresh();
 
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);
 
1962
        if (i < 0) {
 
1963
            for (i = 0; i < nlist; i++)
 
1964
                XtFree(list[i]);
 
1965
            XtFree((XtPointer)list);
 
1966
            XtFree((XtPointer)layouts);
 
1967
            XtFree((XtPointer)mouses);
 
1968
            XtFree((XtPointer)keyboards);
 
1969
            return (-1);
 
1970
        }
 
1971
        if (nlist > 2 && i == nlist - 1) {
 
1972
            if (nlist > 3) {
 
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);
 
1977
                }
 
1978
                ClearScreen();
 
1979
                refresh();
 
1980
                i = DialogMenu("Remove layout",
 
1981
                               "Select which layout to remove",
 
1982
                               13, 60, 4, nlist - 2, list,
 
1983
                               " Remove ", " Cancel ", 0);
 
1984
                if (i < 0) {
 
1985
                    for (i = 0; i < nlist; i++)
 
1986
                        XtFree(list[i]);
 
1987
                    XtFree((XtPointer)list);
 
1988
                    XtFree((XtPointer)layouts);
 
1989
                    XtFree((XtPointer)mouses);
 
1990
                    XtFree((XtPointer)keyboards);
 
1991
                    return (-1);
 
1992
                }
 
1993
                layout = layouts[i];
 
1994
            }
 
1995
            else
 
1996
                layout = layouts[0];
 
1997
            for (i = 0; i < nlist; i++)
 
1998
                XtFree(list[i]);
 
1999
            XtFree((XtPointer)list);
 
2000
            XtFree((XtPointer)layouts);
 
2001
            XtFree((XtPointer)mouses);
 
2002
            XtFree((XtPointer)keyboards);
 
2003
            xf86removeLayout(XF86Config, layout);
 
2004
            return (0);
 
2005
        }
 
2006
        if (i < nlist - 2)
 
2007
            layout = layouts[i];
 
2008
    }
 
2009
    for (i = 0; i < nlist; i++)
 
2010
        XtFree(list[i]);
 
2011
    XtFree((XtPointer)list);
 
2012
    XtFree((XtPointer)layouts);
 
2013
 
 
2014
    if (layout == NULL) {
 
2015
        char label[32];
 
2016
 
 
2017
        layout = (XF86ConfLayoutPtr)XtCalloc(1, sizeof(XF86ConfLayoutRec));
 
2018
        XmuSnprintf(label, sizeof(label), "Layout%d", nlist ? nlist - 2 : 0);
 
2019
        ClearScreen();
 
2020
        refresh();
 
2021
        identifier =
 
2022
            DialogInput("Layout identifier",
 
2023
                        "Enter an identifier for your layout definition:",
 
2024
                        11, 40, label,
 
2025
                        " Next >>", " Cancel ", 0);
 
2026
        if (identifier == NULL) {
 
2027
            XtFree((XtPointer)layout);
 
2028
            XtFree((XtPointer)mouses);
 
2029
            XtFree((XtPointer)keyboards);
 
2030
            return (-1);
 
2031
        }
 
2032
    }
 
2033
    else {
 
2034
        /* So that we can safely change it */
 
2035
        rlayout = layout;
 
2036
        layout = CopyLayout(rlayout);
 
2037
    }
 
2038
 
 
2039
 
 
2040
    mouse = keyboard = NULL;
 
2041
 
 
2042
    /*  Mouse */
 
2043
    piref = NULL;
 
2044
    iref = layout->lay_input_lst;
 
2045
    while (iref) {
 
2046
        if (strcmp(iref->iref_inputdev->inp_driver, "mouse") == 0) {
 
2047
            if (mouse == NULL)
 
2048
                piref = iref;
 
2049
            if (xf86findOption(iref->iref_option_lst, "CorePointer")) {
 
2050
                mouse = iref->iref_inputdev;
 
2051
                piref = iref;
 
2052
                break;
 
2053
            }
 
2054
        }
 
2055
        iref = (XF86ConfInputrefPtr)(iref->list.next);
 
2056
    }
 
2057
    if (mouse == NULL) {
 
2058
        if (piref) {
 
2059
            mref = piref;
 
2060
            mouse = piref->iref_inputdev;
 
2061
            piref->iref_option_lst =
 
2062
                xf86addNewOption(piref->iref_option_lst,
 
2063
                               XtNewString("CorePointer"), NULL);
 
2064
        }
 
2065
        else {
 
2066
            mouse = mouses[0];
 
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;
 
2076
            else {
 
2077
                iref->list.next = layout->lay_input_lst;
 
2078
                layout->lay_input_lst = iref;
 
2079
            }
 
2080
        }
 
2081
    }
 
2082
    else
 
2083
        mref = piref;
 
2084
 
 
2085
    /* XXX list fields are not allocated */
 
2086
    if (nmouses > 1) {
 
2087
        nlist = 0;
 
2088
        list = (char**)XtMalloc(sizeof(char*));
 
2089
        list[nlist++] = mouse->inp_identifier;
 
2090
        input = XF86Config->conf_input_lst;
 
2091
        while (input) {
 
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;
 
2095
            }
 
2096
            input = (XF86ConfInputPtr)(input->list.next);
 
2097
        }
 
2098
        ClearScreen();
 
2099
        refresh();
 
2100
        i = DialogMenu("Select Core Pointer",
 
2101
                       "Select the mouse connected to you computer",
 
2102
                       12, 60, 4, nlist, list, "  Ok  ", " Cancel ", 0);
 
2103
        if (i < 0) {
 
2104
            XtFree((XtPointer)mouses);
 
2105
            XtFree((XtPointer)keyboards);
 
2106
            XtFree((XtPointer)list);
 
2107
            if (layout->lay_identifier == NULL)
 
2108
                XtFree(identifier);
 
2109
            FreeLayout(layout);
 
2110
            return (-1);
 
2111
        }
 
2112
        if (i > 0) {
 
2113
            /* Did not select the default one */
 
2114
            iref = layout->lay_input_lst;
 
2115
            while (iref) {
 
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");
 
2121
                    }
 
2122
                    else
 
2123
                        iref->iref_option_lst =
 
2124
                            xf86addNewOption(iref->iref_option_lst,
 
2125
                                          "CorePointer", NULL);
 
2126
                    option = xf86findOption(mref->iref_option_lst,
 
2127
                                            "CorePointer");
 
2128
                    XtFree(option->opt_name);
 
2129
                    option->opt_name = XtNewString("SendCoreEvents");
 
2130
                    break;
 
2131
                }
 
2132
                iref = (XF86ConfInputrefPtr)(iref->list.next);
 
2133
            }
 
2134
        }
 
2135
 
 
2136
        /* XXX Write code to add/remove more mouses here */
 
2137
    }
 
2138
 
 
2139
 
 
2140
    /*  Keyboard */
 
2141
    piref = NULL;
 
2142
    iref = layout->lay_input_lst;
 
2143
    while (iref) {
 
2144
        if (IS_KBDDRIV(iref->iref_inputdev->inp_driver)) {
 
2145
            if (keyboard == NULL)
 
2146
                piref = iref;
 
2147
            if (xf86findOption(iref->iref_option_lst, "CoreKeyboard")) {
 
2148
                keyboard = iref->iref_inputdev;
 
2149
                piref = iref;
 
2150
                break;
 
2151
            }
 
2152
        }
 
2153
        iref = (XF86ConfInputrefPtr)(iref->list.next);
 
2154
    }
 
2155
    if (keyboard == NULL) {
 
2156
        if (piref) {
 
2157
            kref = piref;
 
2158
            keyboard = piref->iref_inputdev;
 
2159
            piref->iref_option_lst =
 
2160
                xf86addNewOption(piref->iref_option_lst,
 
2161
                               XtNewString("CoreKeyboard"), NULL);
 
2162
        }
 
2163
        else {
 
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;
 
2174
            else {
 
2175
                iref->list.next = layout->lay_input_lst;
 
2176
                layout->lay_input_lst = iref;
 
2177
            }
 
2178
        }
 
2179
    }
 
2180
    else
 
2181
        kref = piref;
 
2182
 
 
2183
    /* XXX list fields are not allocated */
 
2184
    if (nkeyboards > 1) {
 
2185
        nlist = 0;
 
2186
        list = (char**)XtMalloc(sizeof(char*));
 
2187
        list[nlist++] = keyboard->inp_identifier;
 
2188
        input = XF86Config->conf_input_lst;
 
2189
        while (input) {
 
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;
 
2193
            }
 
2194
            input = (XF86ConfInputPtr)(input->list.next);
 
2195
        }
 
2196
        ClearScreen();
 
2197
        refresh();
 
2198
        i = DialogMenu("Select Core Keyboard",
 
2199
                       "Select the keyboard connected to you computer",
 
2200
                       12, 60, 4, nlist, list, "  Ok  ", " Cancel ", 0);
 
2201
        if (i < 0) {
 
2202
            XtFree((XtPointer)mouses);
 
2203
            XtFree((XtPointer)keyboards);
 
2204
            XtFree((XtPointer)list);
 
2205
            if (layout->lay_identifier == NULL)
 
2206
                XtFree(identifier);
 
2207
            FreeLayout(layout);
 
2208
            return (-1);
 
2209
        }
 
2210
        if (i > 0) {
 
2211
            /* Did not select the default one */
 
2212
            iref = layout->lay_input_lst;
 
2213
            while (iref) {
 
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");
 
2219
                    }
 
2220
                    else
 
2221
                        iref->iref_option_lst =
 
2222
                            xf86addNewOption(iref->iref_option_lst,
 
2223
                                          "CoreKeyboard", NULL);
 
2224
                    option = xf86findOption(kref->iref_option_lst,
 
2225
                                            "CoreKeyboard");
 
2226
                    XtFree(option->opt_name);
 
2227
                    option->opt_name = XtNewString("SendCoreEvents");
 
2228
                    break;
 
2229
                }
 
2230
                iref = (XF86ConfInputrefPtr)(iref->list.next);
 
2231
            }
 
2232
        }
 
2233
 
 
2234
        /* XXX Write code to add/remove more keyboards here */
 
2235
    }
 
2236
 
 
2237
    XtFree((XtPointer)mouses);
 
2238
    XtFree((XtPointer)keyboards);
 
2239
 
 
2240
    /* Just one screen */
 
2241
    if (XF86Config->conf_screen_lst->list.next == NULL) {
 
2242
        ClearScreen();
 
2243
        refresh();
 
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."
 
2248
                :
 
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);
 
2252
 
 
2253
        goto LayoutFinish;
 
2254
    }
 
2255
 
 
2256
 
 
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.
 
2260
     */
 
2261
 
 
2262
    /*CONSTCOND*/
 
2263
    while (1) {
 
2264
        static char *screen_opts[] = {
 
2265
            "Add a new screen to layout",
 
2266
            "Remove screen from layout",
 
2267
            "Finish layout configuration",
 
2268
        };
 
2269
 
 
2270
        ClearScreen();
 
2271
        refresh();
 
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);
 
2275
 
 
2276
        /* cancel */
 
2277
        if (i < 0) {
 
2278
            XtFree(identifier);
 
2279
            FreeLayout(layout);
 
2280
            return (-1);
 
2281
        }
 
2282
 
 
2283
        /* add new screen */
 
2284
        else if (i == 0) {
 
2285
            nlist = 0;
 
2286
            list = NULL;
 
2287
            screens = NULL;
 
2288
            screen = XF86Config->conf_screen_lst;
 
2289
            while (screen) {
 
2290
                adj = layout->lay_adjacency_lst;
 
2291
                while (adj) {
 
2292
                    if (adj->adj_screen == screen)
 
2293
                        break;
 
2294
                    adj = (XF86ConfAdjacencyPtr)(adj->list.next);
 
2295
                }
 
2296
                if (adj == NULL) {
 
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;
 
2303
                    ++nlist;
 
2304
                }
 
2305
                screen = (XF86ConfScreenPtr)(screen->list.next);
 
2306
            }
 
2307
 
 
2308
            if (nlist == 0)
 
2309
                continue;
 
2310
 
 
2311
            ClearScreen();
 
2312
            refresh();
 
2313
            i = DialogMenu("Layout add screen", "Choose screen to add:",
 
2314
                           12, 60, 3, nlist, list,
 
2315
                           " Add ", " Cancel ", 0);
 
2316
            if (i >= 0) {
 
2317
                padj = layout->lay_adjacency_lst;
 
2318
                adj = (XF86ConfAdjacencyPtr)
 
2319
                        XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
 
2320
                adj->adj_screen = screens[i];
 
2321
                if (padj == NULL) {
 
2322
                    adj->adj_where = CONF_ADJ_ABSOLUTE;
 
2323
                    layout->lay_adjacency_lst = adj;
 
2324
                }
 
2325
                else {
 
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);
 
2332
                }
 
2333
            }
 
2334
            XtFree((XtPointer)list);
 
2335
            XtFree((XtPointer)screens);
 
2336
        }
 
2337
 
 
2338
        /* remove a screen */
 
2339
        else if (i == 1) {
 
2340
            nlist = 0;
 
2341
            list = NULL;
 
2342
            screens = NULL;
 
2343
            adj = layout->lay_adjacency_lst;
 
2344
 
 
2345
            while (adj) {
 
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;
 
2351
                ++nlist;
 
2352
                adj = (XF86ConfAdjacencyPtr)(adj->list.next);
 
2353
            }
 
2354
 
 
2355
            if (nlist == 0)
 
2356
                continue;
 
2357
 
 
2358
            ClearScreen();
 
2359
            refresh();
 
2360
            i = DialogMenu("Layout remove screen", "Choose screen to remove:",
 
2361
                           12, 60, 3, nlist, list,
 
2362
                           " Remove ", " Cancel ", 0);
 
2363
 
 
2364
            adj = padj = layout->lay_adjacency_lst;
 
2365
            while (adj) {
 
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);
 
2372
                    }
 
2373
                    xf86removeAdjacency(layout, adj);
 
2374
                    break;
 
2375
                }
 
2376
                padj = adj;
 
2377
                adj = (XF86ConfAdjacencyPtr)(padj->list.next);
 
2378
            }
 
2379
            XtFree((XtPointer)list);
 
2380
            XtFree((XtPointer)screens);
 
2381
        }
 
2382
 
 
2383
        /* finish screen configuration */
 
2384
        else
 
2385
            break;
 
2386
    }
 
2387
 
 
2388
LayoutFinish:
 
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;
 
2395
    }
 
2396
    if (rlayout) {
 
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;
 
2402
 
 
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;
 
2406
 
 
2407
            layout->lay_adjacency_lst = tadj;
 
2408
            layout->lay_inactive_lst = tinac;
 
2409
            layout->lay_input_lst = tinp;
 
2410
            FreeLayout(layout);
 
2411
        }
 
2412
        return (0);
 
2413
    }
 
2414
    else {
 
2415
        layout->lay_identifier = identifier;
 
2416
        XF86Config->conf_layout_lst =
 
2417
            xf86addLayout(XF86Config->conf_layout_lst, layout);
 
2418
    }
 
2419
 
 
2420
    return (1);
 
2421
}
 
2422
 
 
2423
static void
 
2424
ClearScreen(void)
 
2425
{
 
2426
    int i, j;
 
2427
 
 
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);
 
2433
    }
 
2434
    touchwin(stdscr);
 
2435
}
 
2436
 
 
2437
static int
 
2438
Dialog(char *title, char * prompt, int height, int width,
 
2439
       char *label1, char *label2, int button)
 
2440
{
 
2441
    int x, x1, x2, y, key, l1len, l2len;
 
2442
    WINDOW *dialog;
 
2443
 
 
2444
    x = (COLS - width) / 2;
 
2445
    y = (LINES - height) / 2;
 
2446
  
 
2447
    dialog = newwin(height, width, y, x);
 
2448
    keypad(dialog, TRUE);
 
2449
 
 
2450
    PaintWindow(dialog, title, 0, 0, height, width);
 
2451
    wattrset(dialog, dialog_attr);
 
2452
    PrintWrap(dialog, prompt, width - 3, 2, 3);
 
2453
 
 
2454
    l1len = strlen(label1);
 
2455
    if (label2)
 
2456
        l2len = strlen(label2);
 
2457
    else {
 
2458
        l2len = button = 0;
 
2459
    }
 
2460
 
 
2461
    x1 = (width - (l1len + l2len)) / (label2 ? 3 : 2);
 
2462
    x2 = x1 + x1 + l1len;
 
2463
    y = height - 3;
 
2464
    if (!button) {
 
2465
        if (label2)
 
2466
            PaintButton(dialog, label2, y, x2, FALSE);
 
2467
        PaintButton(dialog, label1, y, x1, TRUE);
 
2468
    }
 
2469
    else {
 
2470
        PaintButton(dialog, label1, y, x1, FALSE);
 
2471
        if (label2)
 
2472
            PaintButton(dialog, label2, y, x2, TRUE);
 
2473
    }
 
2474
    wrefresh(dialog);
 
2475
 
 
2476
    /*CONSTCOND*/
 
2477
    while (1) {
 
2478
        key = wgetch(dialog);
 
2479
            switch (key) {
 
2480
                case KEY_LEFT:
 
2481
                case KEY_RIGHT:
 
2482
                    if (!button) {
 
2483
                        if (label2) {
 
2484
                            button = 1;
 
2485
                            PaintButton(dialog, label1, y, x1, FALSE);
 
2486
                            PaintButton(dialog, label2, y, x2, TRUE);
 
2487
                        }
 
2488
 
 
2489
                    }
 
2490
                    else {
 
2491
                        if (label2) {
 
2492
                            button = 0;
 
2493
                            PaintButton(dialog, label2, y, x2, FALSE);
 
2494
                            PaintButton(dialog, label1, y, x1, TRUE);
 
2495
                        }
 
2496
                    }
 
2497
                    wrefresh(dialog);
 
2498
                    break;
 
2499
                case ' ':
 
2500
                case '\r':
 
2501
                case '\n':
 
2502
                    delwin(dialog);
 
2503
                    return button;
 
2504
        }
 
2505
    }
 
2506
    /*NOTREACHED*/
 
2507
}
 
2508
 
 
2509
static void
 
2510
PaintWindow(WINDOW *win, char *title_str, int y, int x, int height, int width)
 
2511
{
 
2512
    int i, j;
 
2513
 
 
2514
    if (title_str != NULL) {
 
2515
        j = (width - strlen(title_str)) / 2 - 1;
 
2516
 
 
2517
        wattrset(win, title_attr);
 
2518
        wmove(win, x, y);
 
2519
        for (i = 0; i < j; i++)
 
2520
            waddch(win, ' ');
 
2521
        waddstr(win, title_str);
 
2522
        for (; i < width; i++)
 
2523
            waddch(win, ' ');
 
2524
    }
 
2525
 
 
2526
    wattrset(win, 0);
 
2527
 
 
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);
 
2537
            else if (!j)
 
2538
                waddch(win, highlight_border_attr | ACS_VLINE);
 
2539
            else if (j == width - 1)
 
2540
                waddch(win, shadow_border_attr | ACS_VLINE);
 
2541
            else
 
2542
                waddch(win, dialog_attr | ' ');
 
2543
    }
 
2544
 
 
2545
}
 
2546
 
 
2547
static void
 
2548
PaintBox(WINDOW *win, int y, int x, int height, int width)
 
2549
{
 
2550
    int i, j;
 
2551
 
 
2552
    wattrset(win, 0);
 
2553
 
 
2554
    for (i = 0; i < height; i++) {
 
2555
        wmove(win, y + i, x);
 
2556
        for (j = 0; j < width; j++)
 
2557
            if (!i && !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);
 
2565
            else if (!i)
 
2566
                waddch(win, shadow_border_attr | ACS_HLINE);
 
2567
            else if (i == height - 1)
 
2568
                waddch(win, highlight_border_attr | ACS_HLINE);
 
2569
            else if (!j)
 
2570
                waddch(win, shadow_border_attr | ACS_VLINE);
 
2571
            else if (j == width - 1)
 
2572
                waddch(win, highlight_border_attr | ACS_VLINE);
 
2573
            else
 
2574
                waddch(win, dialog_attr | ' ');
 
2575
    }
 
2576
 
 
2577
}
 
2578
 
 
2579
static void
 
2580
PaintButton(WINDOW *win, char *label, int y, int x, int selected)
 
2581
{
 
2582
    int i, temp;
 
2583
 
 
2584
    wmove(win, y, x);
 
2585
    wattrset(win, selected ? button_active_attr : button_inactive_attr);
 
2586
    waddstr(win, selected ? "[" : " ");
 
2587
    temp = strspn(label, " ");
 
2588
    label += temp;
 
2589
    wattrset(win, selected ? button_active_attr : button_inactive_attr);
 
2590
    for (i = 0; i < temp; i++)
 
2591
      waddch(win, ' ');
 
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);
 
2599
}
 
2600
 
 
2601
static void
 
2602
PrintWrap(WINDOW *win, char *prompt, int width, int y, int x)
 
2603
{
 
2604
    int cur_x, cur_y, len, yinc;
 
2605
    char *word, *tempstr = XtMalloc(strlen(prompt) + 1);
 
2606
 
 
2607
    cur_x = x;
 
2608
    cur_y = y;
 
2609
 
 
2610
    while (*prompt == '\n') {
 
2611
        ++cur_y;
 
2612
        ++prompt;
 
2613
    }
 
2614
 
 
2615
    strcpy(tempstr, prompt);
 
2616
 
 
2617
    for (word = strtok(tempstr, " \n"); word != NULL; word = strtok(NULL, " \n")) {
 
2618
        yinc = 0;
 
2619
        len = strlen(word);
 
2620
        while (prompt[word - tempstr + len + yinc] == '\n')
 
2621
            ++yinc;
 
2622
        if (cur_x + strlen(word) > width) {
 
2623
            cur_y++;
 
2624
            cur_x = x;
 
2625
        }
 
2626
        wmove(win, cur_y, cur_x);
 
2627
        waddstr(win, word);
 
2628
        getyx(win, cur_y, cur_x);
 
2629
        if (yinc) {
 
2630
            cur_y += yinc;
 
2631
            cur_x = x;
 
2632
        }
 
2633
        else
 
2634
            cur_x++;
 
2635
    }
 
2636
 
 
2637
    free(tempstr);
 
2638
}
 
2639
 
 
2640
static int
 
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)
 
2643
{
 
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;
 
2647
 
 
2648
    max_choice = MIN(menu_height, item_no);
 
2649
    max_scroll = MAX(0, item_no - max_choice);
 
2650
 
 
2651
    x = (COLS - width) / 2;
 
2652
    y = (LINES - height) / 2;
 
2653
  
 
2654
    dialog = newwin(height, width, y, x);
 
2655
    keypad(dialog, TRUE);
 
2656
 
 
2657
    PaintWindow(dialog, title, 0, 0, height, width);
 
2658
 
 
2659
    wattrset(dialog, dialog_attr);
 
2660
    PrintWrap(dialog, prompt, width - 3, 2, 3);
 
2661
 
 
2662
    l1len = strlen(label1);
 
2663
    l2len = strlen(label2);
 
2664
 
 
2665
    x1 = (width - (l1len + l2len)) / 3;
 
2666
    x2 = x1 + x1 + l1len;
 
2667
 
 
2668
    menu_width = width - 6;
 
2669
    getyx(dialog, cur_y, cur_x);
 
2670
    box_y = cur_y + 1;
 
2671
    box_x = (width - menu_width) / 2 - 1;
 
2672
 
 
2673
    menu = subwin(dialog, menu_height, menu_width, y + box_y + 1, x + box_x + 1);
 
2674
    keypad(menu, TRUE);
 
2675
 
 
2676
    /* draw a box around the menu items */
 
2677
    PaintBox(dialog, box_y, box_x, menu_height + 2, menu_width + 2);
 
2678
 
 
2679
    item_x = 3;
 
2680
 
 
2681
    if (choice > menu_height) {
 
2682
        scrlx = MIN(max_scroll, choice);
 
2683
        choice -= scrlx;
 
2684
    }
 
2685
 
 
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);
 
2689
    wnoutrefresh(menu);
 
2690
 
 
2691
    x = width / 2 - 11;
 
2692
    y = height - 3;
 
2693
    PaintButton(dialog, label2, y, x2, FALSE);
 
2694
    PaintButton(dialog, label1, y, x1, TRUE);
 
2695
    wrefresh(dialog);
 
2696
 
 
2697
    /*CONSTCOND*/
 
2698
    while (1) {
 
2699
        i = choice;
 
2700
        key = wgetch(dialog);
 
2701
 
 
2702
        if (menu_height > 1 && key == KEY_PPAGE) {
 
2703
            if (!choice) {
 
2704
                if (scrlx) {
 
2705
                    /* Scroll menu down */
 
2706
                    getyx(dialog, cur_y, cur_x);
 
2707
 
 
2708
                    nscroll = max_choice > scrlx ? -scrlx : -max_choice;
 
2709
                    scrollok(menu, TRUE);
 
2710
                    wscrl(menu, nscroll);
 
2711
                    scrollok(menu, FALSE);
 
2712
 
 
2713
                    PaintItem(menu, items[i = scrlx + nscroll], 0, TRUE);
 
2714
                    for (++i; i <= scrlx; i++)
 
2715
                        PaintItem(menu, items[i], i - (scrlx + nscroll), FALSE);
 
2716
                    scrlx += nscroll;
 
2717
                    PaintScroller(menu, scrlx + choice, item_no, menu_height);
 
2718
                    wnoutrefresh(menu);
 
2719
                    wrefresh(dialog);
 
2720
                    continue;
 
2721
                }
 
2722
            }
 
2723
            i = 0;
 
2724
        }
 
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);
 
2730
 
 
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);
 
2736
 
 
2737
                    scrlx += nscroll;
 
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);
 
2742
                    wnoutrefresh(menu);
 
2743
                    wrefresh(dialog);
 
2744
                    continue;
 
2745
                }
 
2746
            }
 
2747
            i = max_choice - 1;
 
2748
        }
 
2749
        else if (key == KEY_UP) {
 
2750
            if (!choice) {
 
2751
                if (scrlx) {
 
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);
 
2757
                        wscrl(menu, - 1);
 
2758
                        scrollok(menu, FALSE);
 
2759
                    }
 
2760
                    scrlx--;
 
2761
                    PaintItem(menu, items[scrlx], 0, TRUE);
 
2762
                    PaintScroller(menu, scrlx + choice, item_no, menu_height);
 
2763
                    wnoutrefresh(menu);
 
2764
                    wrefresh(dialog);
 
2765
                    continue;
 
2766
                }
 
2767
            }
 
2768
            else
 
2769
                i = choice - 1;
 
2770
        }
 
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);
 
2779
                        scroll(menu);
 
2780
                        scrollok(menu, FALSE);
 
2781
                    }
 
2782
                    scrlx++;
 
2783
                    PaintItem(menu, items[scrlx + max_choice - 1], max_choice - 1, TRUE);
 
2784
                    PaintScroller(menu, scrlx + choice, item_no, menu_height);
 
2785
                    wnoutrefresh(menu);
 
2786
                    wrefresh(dialog);
 
2787
                    continue;
 
2788
                }
 
2789
            }
 
2790
            else
 
2791
                i = MIN(choice + 1, item_no - 1);
 
2792
        }
 
2793
 
 
2794
        if (i != choice) {
 
2795
            getyx(dialog, cur_y, cur_x);
 
2796
            PaintItem(menu, items[scrlx + choice], choice, FALSE);
 
2797
 
 
2798
            choice = i;
 
2799
            PaintItem(menu, items[scrlx + choice], choice, TRUE);
 
2800
            PaintScroller(menu, scrlx + choice, item_no, menu_height);
 
2801
            wnoutrefresh(menu);
 
2802
            wmove(dialog, cur_y, cur_x);
 
2803
            wrefresh(dialog);
 
2804
            continue;
 
2805
        }
 
2806
 
 
2807
        switch (key) {
 
2808
            case TAB:
 
2809
            case KEY_LEFT:
 
2810
            case KEY_RIGHT:
 
2811
                if (!button) {
 
2812
                    button = 1;
 
2813
                    PaintButton(dialog, label1, y, x1, FALSE);
 
2814
                    PaintButton(dialog, label2, y, x2, TRUE);
 
2815
                }
 
2816
                else {
 
2817
                    button = 0;
 
2818
                    PaintButton(dialog, label2, y, x2, FALSE);
 
2819
                    PaintButton(dialog, label1, y, x1, TRUE);
 
2820
                }
 
2821
                wrefresh(dialog);
 
2822
                break;
 
2823
            case ' ':
 
2824
            case '\r':
 
2825
            case '\n':
 
2826
                delwin(dialog);
 
2827
                return (!button ? scrlx + choice : -1);
 
2828
            default:
 
2829
                for (i = scrlx + choice + 1; i < item_no; i++)
 
2830
                    if (toupper(items[i][0]) == toupper(key))
 
2831
                        break;
 
2832
                if (i == item_no) {
 
2833
                    for (i = 0; i < scrlx + choice; i++)
 
2834
                        if (toupper(items[i][0]) == toupper(key))
 
2835
                            break;
 
2836
                }
 
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);
 
2842
                        choice = i - scrlx;
 
2843
                    }
 
2844
                    else {
 
2845
                        scrlx = MIN(i, max_scroll);
 
2846
                        choice = i - scrlx;
 
2847
                        for (i = 0; i < max_choice; i++)
 
2848
                            if (i != choice)
 
2849
                                PaintItem(menu, items[scrlx + i], i, FALSE);
 
2850
                    }
 
2851
                    PaintItem(menu, items[scrlx + choice], choice, TRUE);
 
2852
                    PaintScroller(menu, scrlx + choice, item_no, menu_height);
 
2853
                    wnoutrefresh(menu);
 
2854
                    wmove(dialog, cur_y, cur_x);
 
2855
                    wrefresh(dialog);
 
2856
                }
 
2857
                break;
 
2858
        }
 
2859
    }
 
2860
    /*NOTREACHED*/
 
2861
}
 
2862
 
 
2863
static void
 
2864
PaintItem(WINDOW *win, char *item, int choice, int selected)
 
2865
{
 
2866
    int i;
 
2867
 
 
2868
    wattrset(win, selected ? title_attr : dialog_attr);
 
2869
    wmove(win, choice, 1);
 
2870
    for (i = 1; i < menu_width; i++)
 
2871
        waddch(win, ' ');
 
2872
    wmove(win, choice, item_x);
 
2873
    wattrset(win, selected ? title_attr : dialog_attr);
 
2874
    waddstr(win, item);
 
2875
}
 
2876
 
 
2877
static void
 
2878
PaintScroller(WINDOW *win, int offset, int lenght, int visible)
 
2879
{
 
2880
    int i, pos;
 
2881
 
 
2882
    if (lenght > visible)
 
2883
        pos = (visible / (double)lenght) * offset;
 
2884
    else
 
2885
        pos = offset;
 
2886
    wattrset(win, shadow_border_attr);
 
2887
    for (i = 0; i < visible; i++) {
 
2888
        wmove(win, i, 0);
 
2889
        waddch(win, i == pos ? ACS_BLOCK : ACS_VLINE);
 
2890
    }
 
2891
}
 
2892
 
 
2893
static int
 
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)
 
2896
{
 
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;
 
2900
 
 
2901
    max_choice = MIN(menu_height, item_no);
 
2902
    max_scroll = MAX(0, item_no - max_choice);
 
2903
 
 
2904
    x = (COLS - width) / 2;
 
2905
    y = (LINES - height) / 2;
 
2906
  
 
2907
    dialog = newwin(height, width, y, x);
 
2908
    keypad(dialog, TRUE);
 
2909
 
 
2910
    PaintWindow(dialog, title, 0, 0, height, width);
 
2911
 
 
2912
    wattrset(dialog, dialog_attr);
 
2913
    PrintWrap(dialog, prompt, width - 3, 2, 3);
 
2914
 
 
2915
    l1len = strlen(label1);
 
2916
    l2len = strlen(label2);
 
2917
 
 
2918
    x1 = (width - (l1len + l2len)) / 3;
 
2919
    x2 = x1 + x1 + l1len;
 
2920
 
 
2921
    menu_width = width - 6;
 
2922
    getyx(dialog, cur_y, cur_x);
 
2923
    box_y = cur_y + 1;
 
2924
    box_x = (width - menu_width) / 2 - 1;
 
2925
 
 
2926
    menu = subwin(dialog, menu_height, menu_width, y + box_y + 1, x + box_x + 1);
 
2927
    keypad(menu, TRUE);
 
2928
 
 
2929
    /* draw a box around the menu items */
 
2930
    PaintBox(dialog, box_y, box_x, menu_height + 2, menu_width + 2);
 
2931
 
 
2932
    item_x = 3;
 
2933
 
 
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);
 
2937
    wnoutrefresh(menu);
 
2938
 
 
2939
    x = width / 2 - 11;
 
2940
    y = height - 3;
 
2941
    PaintButton(dialog, label2, y, x2, FALSE);
 
2942
    PaintButton(dialog, label1, y, x1, TRUE);
 
2943
    wrefresh(dialog);
 
2944
 
 
2945
    /*CONSTCOND*/
 
2946
    while (1) {
 
2947
        i = choice;
 
2948
        key = wgetch(dialog);
 
2949
 
 
2950
        if (menu_height > 1 && key == KEY_PPAGE) {
 
2951
            if (!choice) {
 
2952
                if (scrlx) {
 
2953
                    /* Scroll menu down */
 
2954
                    getyx(dialog, cur_y, cur_x);
 
2955
 
 
2956
                    nscroll = max_choice > scrlx ? -scrlx : -max_choice;
 
2957
                    scrollok(menu, TRUE);
 
2958
                    wscrl(menu, nscroll);
 
2959
                    scrollok(menu, FALSE);
 
2960
 
 
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]);
 
2965
                    scrlx += nscroll;
 
2966
                    PaintScroller(menu, scrlx + choice, item_no, menu_height);
 
2967
                    wnoutrefresh(menu);
 
2968
                    wrefresh(dialog);
 
2969
                    continue;
 
2970
                }
 
2971
            }
 
2972
            i = 0;
 
2973
        }
 
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);
 
2979
 
 
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);
 
2985
 
 
2986
                    scrlx += nscroll;
 
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);
 
2991
                    wnoutrefresh(menu);
 
2992
                    wrefresh(dialog);
 
2993
                    continue;
 
2994
                }
 
2995
            }
 
2996
            i = max_choice - 1;
 
2997
        }
 
2998
        else if (key == KEY_UP) {
 
2999
            if (!choice) {
 
3000
                if (scrlx) {
 
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);
 
3006
                        wscrl(menu, - 1);
 
3007
                        scrollok(menu, FALSE);
 
3008
                    }
 
3009
                    scrlx--;
 
3010
                    PaintCheckItem(menu, items[scrlx], 0, TRUE, checks[scrlx]);
 
3011
                    PaintScroller(menu, scrlx + choice, item_no, menu_height);
 
3012
                    wnoutrefresh(menu);
 
3013
                    wrefresh(dialog);
 
3014
                    continue;
 
3015
                }
 
3016
            }
 
3017
            else
 
3018
                i = choice - 1;
 
3019
        }
 
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);
 
3028
                        scroll(menu);
 
3029
                        scrollok(menu, FALSE);
 
3030
                    }
 
3031
                    scrlx++;
 
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);
 
3034
                    wnoutrefresh(menu);
 
3035
                    wrefresh(dialog);
 
3036
                    continue;
 
3037
                }
 
3038
            }
 
3039
            else
 
3040
                i = MIN(choice + 1, item_no - 1);
 
3041
        }
 
3042
 
 
3043
        if (i != choice) {
 
3044
            getyx(dialog, cur_y, cur_x);
 
3045
            PaintCheckItem(menu, items[scrlx + choice], choice, FALSE, checks[scrlx + choice]);
 
3046
 
 
3047
            choice = i;
 
3048
            PaintCheckItem(menu, items[scrlx + choice], choice, TRUE, checks[scrlx + choice]);
 
3049
            PaintScroller(menu, scrlx + choice, item_no, menu_height);
 
3050
            wnoutrefresh(menu);
 
3051
            wmove(dialog, cur_y, cur_x);
 
3052
            wrefresh(dialog);
 
3053
            continue;
 
3054
        }
 
3055
 
 
3056
        switch (key) {
 
3057
            case TAB:
 
3058
            case KEY_LEFT:
 
3059
            case KEY_RIGHT:
 
3060
                if (!button) {
 
3061
                    button = 1;
 
3062
                    PaintButton(dialog, label1, y, x1, FALSE);
 
3063
                    PaintButton(dialog, label2, y, x2, TRUE);
 
3064
                }
 
3065
                else {
 
3066
                    button = 0;
 
3067
                    PaintButton(dialog, label2, y, x2, FALSE);
 
3068
                    PaintButton(dialog, label1, y, x1, TRUE);
 
3069
                }
 
3070
                wrefresh(dialog);
 
3071
                break;
 
3072
            case ' ':
 
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);
 
3077
                wnoutrefresh(menu);
 
3078
                wrefresh(dialog);
 
3079
                break;
 
3080
            case '\r':
 
3081
            case '\n':
 
3082
                delwin(dialog);
 
3083
                return (!button ? 0 : -1);
 
3084
            default:
 
3085
                for (i = scrlx + choice + 1; i < item_no; i++)
 
3086
                    if (toupper(items[i][0]) == toupper(key))
 
3087
                        break;
 
3088
                if (i == item_no) {
 
3089
                    for (i = 0; i < scrlx + choice; i++)
 
3090
                        if (toupper(items[i][0]) == toupper(key))
 
3091
                            break;
 
3092
                }
 
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]);
 
3098
                        choice = i - scrlx;
 
3099
                    }
 
3100
                    else {
 
3101
                        scrlx = MIN(i, max_scroll);
 
3102
                        choice = i - scrlx;
 
3103
                        for (i = 0; i < max_choice; i++)
 
3104
                            if (i != choice)
 
3105
                                PaintCheckItem(menu, items[scrlx + i], i, FALSE, checks[scrlx + i]);
 
3106
                    }
 
3107
                    PaintCheckItem(menu, items[scrlx + choice], choice, TRUE, checks[scrlx + choice]);
 
3108
                    PaintScroller(menu, scrlx + choice, item_no, menu_height);
 
3109
                    wnoutrefresh(menu);
 
3110
                    wmove(dialog, cur_y, cur_x);
 
3111
                    wrefresh(dialog);
 
3112
                }
 
3113
                break;
 
3114
        }
 
3115
    }
 
3116
    /*NOTREACHED*/
 
3117
}
 
3118
 
 
3119
static void
 
3120
PaintCheckItem(WINDOW *win, char *item, int choice, int selected, int checked)
 
3121
{
 
3122
    int i;
 
3123
 
 
3124
    wattrset(win, selected ? title_attr : dialog_attr);
 
3125
    wmove(win, choice, 1);
 
3126
    for (i = 1; i < menu_width; i++)
 
3127
        waddch(win, ' ');
 
3128
    wmove(win, choice, item_x);
 
3129
    wattrset(win, selected ? title_attr : dialog_attr);
 
3130
    wprintw(win, "[%c] ", checked ? 'X' : ' ');
 
3131
    waddstr(win, item);
 
3132
}
 
3133
 
 
3134
static char *
 
3135
DialogInput(char *title, char *prompt, int height, int width, char *init,
 
3136
            char *label1, char *label2, int def_button)
 
3137
{
 
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];
 
3141
    WINDOW *dialog;
 
3142
 
 
3143
    x = (COLS - width) / 2;
 
3144
    y = (LINES - height) / 2;
 
3145
 
 
3146
    dialog = newwin(height, width, y, x);
 
3147
    keypad(dialog, TRUE);
 
3148
 
 
3149
    PaintWindow(dialog, title, 0, 0, height, width);
 
3150
 
 
3151
    wattrset(dialog, dialog_attr);
 
3152
    PrintWrap(dialog, prompt, width - 3, 2, 3);
 
3153
 
 
3154
    l1len = strlen(label1);
 
3155
    l2len = strlen(label2);
 
3156
 
 
3157
    x1 = (width - (l1len + l2len)) / 3;
 
3158
    x2 = x1 + x1 + l1len;
 
3159
 
 
3160
    box_width = width - 6;
 
3161
    getyx(dialog, y, x);
 
3162
    box_y = y + 2;
 
3163
    box_x = (width - box_width) / 2;
 
3164
    PaintBox(dialog, y + 1, box_x - 1, 3, box_width + 2);
 
3165
 
 
3166
    x = width / 2 - 11;
 
3167
    y = height - 3;
 
3168
    PaintButton(dialog, label2, y, x2, def_button == 1);
 
3169
    PaintButton(dialog, label1, y, x1, def_button == 0);
 
3170
 
 
3171
    memset(instr, '\0', sizeof(instr));
 
3172
    wmove(dialog, box_y, box_x);
 
3173
    wattrset(dialog, dialog_attr);
 
3174
    if (init)
 
3175
        strncpy(instr, init, sizeof(instr) - 2);
 
3176
 
 
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]);
 
3183
    }
 
3184
    else
 
3185
        waddstr(dialog, instr);
 
3186
 
 
3187
    wmove(dialog, box_y, box_x + input_x);
 
3188
  
 
3189
    wrefresh(dialog);
 
3190
 
 
3191
    while (1) {
 
3192
        key = wgetch(dialog);
 
3193
        if (button == -1) {         /* Input box selected */
 
3194
            switch (key) {
 
3195
                case TAB:
 
3196
                case KEY_UP:
 
3197
                case KEY_DOWN:
 
3198
                    break;
 
3199
                case KEY_LEFT:
 
3200
                    if (scrlx && !input_x) {
 
3201
                        --scrlx;
 
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);
 
3206
                        wrefresh(dialog);
 
3207
                    }
 
3208
                    else if (input_x) {
 
3209
                        wmove(dialog, box_y, --input_x + box_x);
 
3210
                        wrefresh(dialog);
 
3211
                    }
 
3212
                    continue;
 
3213
                case KEY_RIGHT:
 
3214
                    if (input_x + scrlx < len) {
 
3215
                        if (input_x == box_width - 1) {
 
3216
                            ++scrlx;
 
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);
 
3221
                            wrefresh(dialog);
 
3222
                        }
 
3223
                        else {
 
3224
                            wmove(dialog, box_y, ++input_x + box_x);
 
3225
                            wrefresh(dialog);
 
3226
                        }
 
3227
                    }
 
3228
                    continue;
 
3229
                case KEY_BACKSPACE:
 
3230
                case 0177:
 
3231
#if defined(__SCO__) || defined(__UNIXWARE__)
 
3232
                case '\b':
 
3233
#endif
 
3234
                    if (input_x || scrlx) {
 
3235
                        wattrset(dialog, dialog_attr);
 
3236
 
 
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';
 
3242
 
 
3243
                        if (!input_x) {
 
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;
 
3249
                        }
 
3250
                        else {
 
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, ' ');
 
3257
                        }
 
3258
                        wmove(dialog, box_y, input_x + box_x);
 
3259
                        wrefresh(dialog);
 
3260
                    }
 
3261
                    continue;
 
3262
                case KEY_HOME:
 
3263
                case CONTROL_A:
 
3264
                    wmove(dialog, box_y, box_x);
 
3265
                    if (scrlx != 0) {
 
3266
                        scrlx = 0;
 
3267
                        for (i = 0; i < box_width; i++)
 
3268
                            waddch(dialog, instr[i] ? instr[i] : ' ');
 
3269
                    }
 
3270
                    input_x = 0;
 
3271
                    wmove(dialog, box_y, box_x);
 
3272
                    wrefresh(dialog);
 
3273
                    break;
 
3274
                case CONTROL_D:
 
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);
 
3286
                        wrefresh(dialog);
 
3287
                    }
 
3288
                    break;
 
3289
                case CONTROL_E:
 
3290
                case KEY_END:
 
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);
 
3298
                        wrefresh(dialog);
 
3299
                    }
 
3300
                    else {
 
3301
                        input_x = len - scrlx;
 
3302
                        wmove(dialog, box_y, input_x + box_x);
 
3303
                        wrefresh(dialog);
 
3304
                    }
 
3305
                    break;
 
3306
                case CONTROL_K:
 
3307
                    if (len) {
 
3308
                        for (i = input_x; i < box_width; i++)
 
3309
                            waddch(dialog, ' ');
 
3310
                        for (i = scrlx + input_x; i < len; i++)
 
3311
                            instr[i] = '\0';
 
3312
                        len = scrlx + input_x;
 
3313
                        wmove(dialog, box_y, box_x + input_x);
 
3314
                        wrefresh(dialog);
 
3315
                    }
 
3316
                    break;
 
3317
                default:
 
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));
 
3325
                            }
 
3326
                            instr[scrlx + input_x] = key;
 
3327
                            instr[++len] = '\0';
 
3328
                            if (input_x == box_width - 1) {
 
3329
                                scrlx++;
 
3330
                                wmove(dialog, box_y, box_x);
 
3331
                                for (i = 0; i < box_width - 1; i++)
 
3332
                                    waddch(dialog, instr[scrlx + i]);
 
3333
                            }
 
3334
                            else {
 
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);
 
3340
                            }
 
3341
                            wrefresh(dialog);
 
3342
                        }
 
3343
                        else
 
3344
                            flash();        /* Alarm user about overflow */
 
3345
                        continue;
 
3346
                    }
 
3347
                }
 
3348
            }
 
3349
 
 
3350
        switch (key) {
 
3351
            case KEY_UP:
 
3352
            case KEY_LEFT:
 
3353
                switch (button) {
 
3354
                    case -1:
 
3355
                        button = 1;     /* Indicates "Cancel" button is selected */
 
3356
                        PaintButton(dialog, label1, y, x1, FALSE);
 
3357
                        PaintButton(dialog, label2, y, x2, TRUE);
 
3358
                        wrefresh(dialog);
 
3359
                        break;
 
3360
                    case 0:
 
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);
 
3365
                        wrefresh(dialog);
 
3366
                        break;
 
3367
                    case 1:
 
3368
                        button = 0;     /* Indicates "OK" button is selected */
 
3369
                        PaintButton(dialog, label2, y, x2, FALSE);
 
3370
                        PaintButton(dialog, label1, y, x1, TRUE);
 
3371
                        wrefresh(dialog);
 
3372
                        break;
 
3373
                }
 
3374
                break;
 
3375
            case TAB:
 
3376
            case KEY_DOWN:
 
3377
            case KEY_RIGHT:
 
3378
                switch (button) {
 
3379
                    case -1:
 
3380
                        button = 0;     /* Indicates "OK" button is selected */
 
3381
                        PaintButton(dialog, label2, y, x2, FALSE);
 
3382
                        PaintButton(dialog, label1, y, x1, TRUE);
 
3383
                        wrefresh(dialog);
 
3384
                        break;
 
3385
                    case 0:
 
3386
                        button = 1;     /* Indicates "Cancel" button is selected */
 
3387
                        PaintButton(dialog, label1, y, x1, FALSE);
 
3388
                        PaintButton(dialog, label2, y, x2, TRUE);
 
3389
                        wrefresh(dialog);
 
3390
                        break;
 
3391
                    case 1:
 
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);
 
3396
                        wrefresh(dialog);
 
3397
                        break;
 
3398
                }
 
3399
                break;
 
3400
            case ' ':
 
3401
            case '\r':
 
3402
            case '\n':
 
3403
                delwin(dialog);
 
3404
                return (button != 1 ? XtNewString(instr) : NULL);
 
3405
        }
 
3406
    }
 
3407
}