First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / utils / xorgcfg / vidmode.c
blob2d613b6df66a3102730c35b385ef001db0421feb
1 /*
2 * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * CONECTIVA LINUX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
22 * Except as contained in this notice, the name of Conectiva Linux shall
23 * not be used in advertising or otherwise to promote the sale, use or other
24 * dealings in this Software without prior written authorization from
25 * Conectiva Linux.
27 * Author: Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
32 * Most of the code here is based on the xvidtune code.
35 #include "vidmode.h"
36 #include <X11/Xaw/Command.h>
37 #include <X11/Xaw/Form.h>
38 #include <X11/Xaw/Label.h>
39 #include <X11/Xaw/MenuButton.h>
40 #include <X11/Xaw/Repeater.h>
41 #include <X11/Shell.h>
42 #include <X11/Xaw/AsciiText.h>
43 #include <X11/Xaw/Dialog.h>
44 #include <X11/Xaw/SimpleMenP.h>
45 #include <X11/Xaw/SmeBSB.h>
46 #include <X11/Xaw/Toggle.h>
47 #include "xf86config.h"
49 #define V_FLAG_MASK 0x1FF
50 #define V_PHSYNC 0x001
51 #define V_NHSYNC 0x002
52 #define V_PVSYNC 0x004
53 #define V_NVSYNC 0x008
54 #define V_INTERLACE 0x010
55 #define V_DBLSCAN 0x020
56 #define V_CSYNC 0x040
57 #define V_PCSYNC 0x080
58 #define V_NCSYNC 0x100
60 #define LEFT 0
61 #define RIGHT 1
62 #define UP 2
63 #define DOWN 3
64 #define WIDER 4
65 #define TALLER 5
66 #define NARROWER 6
67 #define SHORTER 7
69 #define HDISPLAY 0
70 #define VDISPLAY 1
71 #define HSYNCSTART 2
72 #define HSYNCEND 3
73 #define HTOTAL 4
74 #define VSYNCSTART 5
75 #define VSYNCEND 6
76 #define VTOTAL 7
77 #define FLAGS 8
78 #define CLOCK 9
79 #define HSYNC 10
80 #define VSYNC 11
82 #define MINMAJOR 2
83 #define MINMINOR 0
86 * Types
88 typedef struct {
89 char *ident;
90 XF86VidModeModeInfo info;
91 } xf86cfgVesaModeInfo;
94 * Prototypes
96 static Bool GetModeLine(Bool);
97 static void StartAdjustMonitorCallback(Widget, XtPointer, XtPointer);
98 static void AdjustMonitorCallback(Widget, XtPointer, XtPointer);
99 static void EndAdjustMonitorCallback(Widget, XtPointer, XtPointer);
100 static void SetLabel(int, int);
101 static void UpdateSyncRates(Bool);
102 static int VidmodeError(Display*, XErrorEvent*);
103 static void CleanUp(Display*);
104 static void ApplyCallback(Widget, XtPointer, XtPointer);
105 static void AutoCallback(Widget, XtPointer, XtPointer);
106 static void RestoreCallback(Widget, XtPointer, XtPointer);
107 static void SelectCallback(Widget, XtPointer, XtPointer);
108 static void SelectMonitorCallback(Widget, XtPointer, XtPointer);
109 static void SwitchCallback(Widget, XtPointer, XtPointer);
110 static void SetLabels(void);
111 static void UpdateCallback(Widget, XtPointer, XtPointer);
112 static void ChangeScreenCallback(Widget, XtPointer, XtPointer);
113 static void SetLabelAndModeline(void);
114 static void AddVesaModeCallback(Widget, XtPointer, XtPointer);
115 static void GetModes(void);
116 static void AddModeCallback(Widget, XtPointer, XtPointer);
117 static void TestCallback(Widget, XtPointer, XtPointer);
118 static void TestTimeout(XtPointer, XtIntervalId*);
119 static void StopTestCallback(Widget, XtPointer, XtPointer);
120 static int ForceAddMode(void);
121 static int AddMode(void);
123 * Initialization
125 extern Widget work;
126 Widget vtune;
127 static Widget apply, automatic, restore, mode, menu, screenb, screenp;
128 static Bool autoflag;
129 static xf86cfgVidmode *vidtune;
130 static XF86VidModeModeLine modeline, orig_modeline;
131 static int dot_clock, hsync_rate, vsync_rate, hitError;
132 static int screenno;
133 static int (*XtErrorFunc)(Display*, XErrorEvent*);
134 static Widget values[VSYNC + 1], repeater, monitor,
135 monitorb, add, text, vesap, forceshell, testshell, addshell;
136 static int MajorVersion, MinorVersion, EventBase, ErrorBase;
137 static XtIntervalId timeout;
139 /* The information bellow is extracted from
140 * xc/programs/Xserver/hw/xfree86/etc/vesamodes
141 * If that file is changed, please update the table bellow also. Or even
142 * better, write a script to generate the table.
144 static xf86cfgVesaModeInfo vesamodes[] = {
146 "640x350 @ 85Hz (VESA) hsync: 37.9kHz",
148 31500, 640, 672, 736, 832, 0, 350, 382, 385, 445,
149 V_PHSYNC | V_NVSYNC
153 "640x400 @ 85Hz (VESA) hsync: 37.9kHz",
155 31500, 640, 672, 736, 832, 0, 400, 401, 404, 445,
156 V_NHSYNC | V_PVSYNC
160 "720x400 @ 85Hz (VESA) hsync: 37.9kHz",
162 35500, 720, 756, 828, 936, 0, 400, 401, 404, 446,
163 V_NHSYNC | V_PVSYNC
167 "640x480 @ 60Hz (Industry standard) hsync: 31.5kHz",
169 25200, 640, 656, 752, 800, 0, 480, 490, 492, 525,
170 V_NHSYNC | V_NVSYNC
174 "640x480 @ 72Hz (VESA) hsync: 37.9kHz",
176 31500, 640, 664, 704, 832, 0, 480, 489, 491, 520,
177 V_NHSYNC | V_NVSYNC
181 "640x480 @ 75Hz (VESA) hsync: 37.5kHz",
183 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500,
184 V_NHSYNC | V_NVSYNC
188 "640x480 @ 85Hz (VESA) hsync: 43.3kHz",
190 36000, 640, 696, 752, 832, 0, 480, 481, 484, 509,
191 V_NHSYNC | V_NVSYNC
195 "800x600 @ 56Hz (VESA) hsync: 35.2kHz",
197 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625,
198 V_PHSYNC | V_PVSYNC
202 "800x600 @ 60Hz (VESA) hsync: 37.9kHz",
204 400000, 800, 840, 968, 1056, 0, 600, 601, 605, 628,
205 V_PHSYNC | V_PVSYNC
209 "800x600 @ 72Hz (VESA) hsync: 48.1kHz",
211 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666,
212 V_PHSYNC | V_PVSYNC
216 "800x600 @ 75Hz (VESA) hsync: 46.9kHz",
218 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625,
219 V_PHSYNC | V_PVSYNC
223 "800x600 @ 85Hz (VESA) hsync: 53.7kHz",
225 563000, 800, 832, 896, 1048, 0, 600, 601, 604, 631,
226 V_PHSYNC | V_PVSYNC
230 "1024x768i @ 43Hz (industry standard) hsync: 35.5kHz",
232 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 776, 817,
233 V_PHSYNC | V_PVSYNC | V_INTERLACE
237 "1024x768 @ 60Hz (VESA) hsync: 48.4kHz",
239 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806,
240 V_NHSYNC | V_NVSYNC
244 "1024x768 @ 70Hz (VESA) hsync: 56.5kHz",
246 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806,
247 V_NHSYNC | V_NVSYNC
251 "1024x768 @ 75Hz (VESA) hsync: 60.0kHz",
253 78800, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800,
254 V_PHSYNC | V_PVSYNC
258 "1024x768 @ 85Hz (VESA) hsync: 68.7kHz",
260 94500, 1024, 1072, 1168, 1376, 0, 768, 769, 772, 808,
261 V_PHSYNC | V_PVSYNC
265 "1152x864 @ 75Hz (VESA) hsync: 67.5kHz",
267 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900,
268 V_PHSYNC | V_PVSYNC
272 "1280x960 @ 60Hz (VESA) hsync: 60.0kHz",
274 108000, 1280, 1376, 1488, 1800, 0, 960, 961, 964, 1000,
275 V_PHSYNC | V_PVSYNC
279 "1280x960 @ 85Hz (VESA) hsync: 85.9kHz",
281 148500, 1280, 1344, 1504, 1728, 0, 960, 961, 964, 1011,
282 V_PHSYNC | V_PVSYNC
286 "1280x1024 @ 60Hz (VESA) hsync: 64.0kHz",
288 108000, 1280, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066,
289 V_PHSYNC | V_PVSYNC
293 "1280x1024 @ 75Hz (VESA) hsync: 80.0kHz",
295 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066,
296 V_PHSYNC | V_PVSYNC
300 "1280x1024 @ 85Hz (VESA) hsync: 91.1kHz",
302 157500, 1280, 1344, 1504, 1728, 0, 1024, 1025, 1028, 1072,
303 V_PHSYNC | V_PVSYNC
307 "1600x1200 @ 60Hz (VESA) hsync: 75.0kHz",
309 162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
310 V_PHSYNC | V_PVSYNC
314 "1600x1200 @ 65Hz (VESA) hsync: 81.3kHz",
316 175500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
317 V_PHSYNC | V_PVSYNC
321 "1600x1200 @ 70Hz (VESA) hsync: 87.5kHz",
323 189000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
324 V_PHSYNC | V_PVSYNC
328 "1600x1200 @ 75Hz (VESA) hsync: 93.8kHz",
330 202500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
331 V_PHSYNC | V_PVSYNC
335 "1600x1200 @ 85Hz (VESA) hsync: 106.3kHz",
337 229500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
338 V_PHSYNC | V_PVSYNC
342 "1792x1344 @ 60Hz (VESA) hsync: 83.6kHz",
344 204800, 1792, 1920, 2120, 2448, 0, 1344, 1345, 1348, 1394,
345 V_NHSYNC | V_PVSYNC
349 "1792x1344 @ 75Hz (VESA) hsync: 106.3kHz",
351 261000, 1792, 1888, 2104, 2456, 0, 1344, 1345, 1348, 1417,
352 V_NHSYNC | V_PVSYNC
356 "1856x1392 @ 60Hz (VESA) hsync: 86.3kHz",
358 218300, 1856, 1952, 2176, 2528, 0, 1392, 1393, 1396, 1439,
359 V_NHSYNC | V_PVSYNC
363 "1856x1392 @ 75Hz (VESA) hsync: 112.5kHz",
365 288000, 1856, 1984, 2208, 2560, 0, 1392, 1393, 1396, 1500,
366 V_NHSYNC | V_PVSYNC
370 "1920x1440 @ 60Hz (VESA) hsync: 90.0kHz",
372 234000, 1920, 2048, 2256, 2600, 0, 1440, 1441, 1444, 1500,
373 V_NHSYNC | V_PVSYNC
377 "1920x1440 @ 75Hz (VESA) hsync: 112.5kHz",
379 297000, 1920, 2064, 2288, 2640, 0, 1440, 1441, 1444, 1500,
380 V_NHSYNC | V_PVSYNC
386 * Implementation
388 Bool
389 VideoModeInitialize(void)
391 Widget form;
392 char dispstr[128], *ptr, *tmp;
394 static char *names[] = {
395 NULL,
396 NULL,
397 "hsyncstart",
398 "hsyncend",
399 "htotal",
400 "vsyncstart",
401 "vsyncend",
402 "vtotal",
403 "flags",
404 "clock",
405 "hsync",
406 "vsync",
408 static char *vnames[] = {
409 NULL,
410 NULL,
411 "v-hsyncstart",
412 "v-hsyncend",
413 "v-htotal",
414 "v-vsyncstart",
415 "v-vsyncend",
416 "v-vtotal",
417 "v-flags",
418 "v-clock",
419 "v-hsync",
420 "v-vsync",
422 Widget rep;
423 int i;
425 if (!XF86VidModeQueryVersion(XtDisplay(toplevel),
426 &MajorVersion, &MinorVersion)) {
427 fprintf(stderr, "Unable to query video extension version\n");
428 return (False);
430 else if (!XF86VidModeQueryExtension(XtDisplay(toplevel),
431 &EventBase, &ErrorBase)) {
432 fprintf(stderr, "Unable to query video extension information\n");
433 return (False);
435 else if (MajorVersion < MINMAJOR ||
436 (MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) {
437 fprintf(stderr,
438 "Xserver is running an old XFree86-VidModeExtension version"
439 " (%d.%d)\n", MajorVersion, MinorVersion);
440 fprintf(stderr, "Minimum required version is %d.%d\n",
441 MINMAJOR, MINMINOR);
442 return (False);
444 else
445 InitializeVidmodes();
447 vtune = XtCreateWidget("vidtune", formWidgetClass,
448 work, NULL, 0);
450 (void) XtVaCreateManagedWidget("vesaB", menuButtonWidgetClass, vtune,
451 XtNmenuName, "vesaP", NULL);
452 vesap = XtCreatePopupShell("vesaP", simpleMenuWidgetClass, vtune, NULL, 0);
453 for (i = 0; i < sizeof(vesamodes) / sizeof(vesamodes[0]); i++) {
454 rep = XtCreateManagedWidget(vesamodes[i].ident, smeBSBObjectClass,
455 vesap, NULL, 0);
456 XtAddCallback(rep, XtNcallback, AddVesaModeCallback,
457 (XtPointer)&vesamodes[i]);
460 rep = XtCreateManagedWidget("prev", commandWidgetClass, vtune, NULL, 0);
461 XtAddCallback(rep, XtNcallback, SwitchCallback, (XtPointer)-1);
462 mode = XtCreateManagedWidget("mode", menuButtonWidgetClass, vtune, NULL, 0);
463 rep = XtCreateManagedWidget("next", commandWidgetClass, vtune, NULL, 0);
464 XtAddCallback(rep, XtNcallback, SwitchCallback, (XtPointer)1);
466 screenp = XtCreatePopupShell("screenP", simpleMenuWidgetClass, vtune,
467 NULL, 0);
469 XmuSnprintf(dispstr, sizeof(dispstr), "%s",
470 DisplayString(XtDisplay(toplevel)));
471 ptr = strrchr(dispstr, '.');
472 tmp = strrchr(dispstr, ':');
473 if (tmp != NULL && ptr != NULL && ptr > tmp)
474 *ptr = '\0';
476 for (i = 0; i < ScreenCount(XtDisplay(toplevel)); i++) {
477 char name[128];
479 XmuSnprintf(name, sizeof(name), "%s.%d", dispstr, i);
480 rep = XtCreateManagedWidget(name, smeBSBObjectClass, screenp,
481 NULL, 0);
482 XtAddCallback(rep, XtNcallback, ChangeScreenCallback,
483 (XtPointer)(long)i);
484 if (i == 0) {
485 screenb = XtVaCreateManagedWidget("screenB", menuButtonWidgetClass,
486 vtune,
487 XtNmenuName, "screenP",
488 XtNlabel, name,
489 NULL);
492 XtRealizeWidget(screenp);
494 rep = XtCreateManagedWidget("up", repeaterWidgetClass,
495 vtune, NULL, 0);
496 XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
497 XtAddCallback(rep, XtNcallback,
498 AdjustMonitorCallback, (XtPointer)UP);
499 XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
500 rep = XtCreateManagedWidget("left", repeaterWidgetClass,
501 vtune, NULL, 0);
502 XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
503 XtAddCallback(rep, XtNcallback,
504 AdjustMonitorCallback, (XtPointer)LEFT);
505 XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
506 XtCreateManagedWidget("monitor", simpleWidgetClass, vtune, NULL, 0);
507 rep = XtCreateManagedWidget("right", repeaterWidgetClass,
508 vtune, NULL, 0);
509 XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
510 XtAddCallback(rep, XtNcallback,
511 AdjustMonitorCallback, (XtPointer)RIGHT);
512 XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
513 rep = XtCreateManagedWidget("down", repeaterWidgetClass,
514 vtune, NULL, 0);
515 XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
516 XtAddCallback(rep, XtNcallback,
517 AdjustMonitorCallback, (XtPointer)DOWN);
518 XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
519 rep = XtCreateManagedWidget("wider", repeaterWidgetClass,
520 vtune, NULL, 0);
521 XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
522 XtAddCallback(rep, XtNcallback,
523 AdjustMonitorCallback, (XtPointer)WIDER);
524 XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
525 rep = XtCreateManagedWidget("narrower", repeaterWidgetClass,
526 vtune, NULL, 0);
527 XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
528 XtAddCallback(rep, XtNcallback,
529 AdjustMonitorCallback, (XtPointer)NARROWER);
530 XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
531 rep = XtCreateManagedWidget("shorter", repeaterWidgetClass,
532 vtune, NULL, 0);
533 XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
534 XtAddCallback(rep, XtNcallback,
535 AdjustMonitorCallback, (XtPointer)SHORTER);
536 XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
537 rep = XtCreateManagedWidget("taller", repeaterWidgetClass,
538 vtune, NULL, 0);
539 XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
540 XtAddCallback(rep, XtNcallback,
541 AdjustMonitorCallback, (XtPointer)TALLER);
542 XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
544 automatic = XtCreateManagedWidget("auto", toggleWidgetClass, vtune, NULL, 0);
545 XtAddCallback(automatic, XtNcallback, AutoCallback, NULL);
546 apply = XtCreateManagedWidget("apply", commandWidgetClass, vtune, NULL, 0);
547 XtAddCallback(apply, XtNcallback, ApplyCallback, NULL);
548 restore = XtCreateManagedWidget("restore", commandWidgetClass, vtune, NULL, 0);
549 XtAddCallback(restore, XtNcallback, RestoreCallback, NULL);
550 rep = XtCreateManagedWidget("update", commandWidgetClass, vtune, NULL, 0);
551 XtAddCallback(rep, XtNcallback, UpdateCallback, NULL);
552 rep = XtCreateManagedWidget("test", commandWidgetClass, vtune, NULL, 0);
553 XtAddCallback(rep, XtNcallback, TestCallback, NULL);
555 form = XtCreateManagedWidget("form", formWidgetClass, vtune, NULL, 0);
556 for (i = 2; i < VSYNC + 1; i++) {
557 (void) XtCreateManagedWidget(names[i], labelWidgetClass,
558 form, NULL, 0);
559 values[i] = XtCreateManagedWidget(vnames[i], labelWidgetClass,
560 form, NULL, 0);
563 add = XtCreateManagedWidget("add", commandWidgetClass, vtune, NULL, 0);
564 XtAddCallback(add, XtNcallback, AddModeCallback, NULL);
565 XtCreateManagedWidget("addto", labelWidgetClass, vtune, NULL, 0);
566 monitorb = XtCreateManagedWidget("ident", menuButtonWidgetClass, vtune,
567 NULL, 0);
568 XtCreateManagedWidget("as", labelWidgetClass, vtune, NULL, 0);
569 text = XtVaCreateManagedWidget("text", asciiTextWidgetClass, vtune,
570 XtNeditType, XawtextEdit, NULL);
572 XtRealizeWidget(vtune);
574 return (True);
577 void
578 InitializeVidmodes(void)
580 int i;
581 Display *display = XtDisplay(toplevel);
583 computer.num_vidmodes = ScreenCount(display);
584 computer.vidmodes = (xf86cfgVidmode**)
585 XtMalloc(sizeof(xf86cfgVidmode*) * computer.num_vidmodes);
586 for (i = 0; i < computer.num_vidmodes; i++) {
588 computer.vidmodes[i] = (xf86cfgVidmode*)
589 XtCalloc(1, sizeof(xf86cfgVidmode));
590 computer.vidmodes[i]->screen = i;
594 void
595 VideoModeConfigureStart(void)
597 vidtune = computer.vidmodes[screenno];
599 XtSetSensitive(vtune, vidtune != NULL);
600 if (!XtIsManaged(vtune))
601 XtManageChild(vtune);
602 else
603 XtMapWidget(vtune);
604 if (vidtune != NULL) {
605 Arg args[1];
606 Boolean state;
607 XF86ConfMonitorPtr mon;
608 static char menuName[16];
609 static int menuN;
611 XtErrorFunc = XSetErrorHandler(VidmodeError);
612 XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, True);
613 GetModeLine(True);
614 GetModes();
616 SetLabels();
617 XtSetArg(args[0], XtNstate, &state);
618 XtGetValues(automatic, args, 1);
619 XtSetSensitive(apply, !state);
620 autoflag = state;
622 if (monitor)
623 XtDestroyWidget(monitor);
624 XmuSnprintf(menuName, sizeof(menuName), "menuP%d", menuN);
625 menuN = !menuN;
626 monitor = XtCreatePopupShell(menuName, simpleMenuWidgetClass,
627 vtune, NULL, 0);
628 XtVaSetValues(monitorb, XtNmenuName, menuName, NULL);
630 mon = XF86Config->conf_monitor_lst;
631 while (mon != NULL) {
632 Widget sme = XtCreateManagedWidget(mon->mon_identifier,
633 smeBSBObjectClass,
634 monitor, NULL, 0);
635 XtAddCallback(sme, XtNcallback,
636 SelectMonitorCallback, (XtPointer)mon);
638 /* guess the monitor at a given screen and/or
639 * updates configuration if a monitor was removed from the
640 * configuration.
642 if (XF86Config->conf_layout_lst) {
643 XF86ConfAdjacencyPtr adj = XF86Config->conf_layout_lst->
644 lay_adjacency_lst;
646 while (adj != NULL) {
647 if (adj->adj_screen != NULL) {
648 if (adj->adj_screen->scrn_monitor == mon &&
649 adj->adj_scrnum >= 0 &&
650 adj->adj_scrnum < ScreenCount(XtDisplay(toplevel))) {
651 if (computer.vidmodes[adj->adj_scrnum]->monitor ==
652 NULL || computer.vidmodes[adj->adj_scrnum]->
653 monitor == adj->adj_screen->scrn_monitor) {
654 computer.vidmodes[adj->adj_scrnum]->monitor =
655 adj->adj_screen->scrn_monitor;
656 break;
658 else
659 computer.vidmodes[adj->adj_scrnum]->monitor =
660 NULL;
663 adj = (XF86ConfAdjacencyPtr)(adj->list.next);
666 mon = (XF86ConfMonitorPtr)(mon->list.next);
668 SetLabelAndModeline();
672 void
673 VideoModeConfigureEnd(void)
675 XtUnmapWidget(vtune);
676 if (vidtune != NULL) {
677 XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, False);
678 XSetErrorHandler(XtErrorFunc);
680 vidtune = NULL;
683 static void
684 SetLabelAndModeline(void)
686 if (vidtune->monitor != NULL) {
687 char string[32];
689 XtVaSetValues(monitorb, XtNlabel,
690 vidtune->monitor->mon_identifier, NULL);
691 XtSetSensitive(add, True);
693 if (modeline.htotal && modeline.vtotal)
694 XmuSnprintf(string, sizeof(string), "%dx%d@%d",
695 modeline.hdisplay, modeline.vdisplay,
696 (int)((double)dot_clock / (double)modeline.htotal * 1000.0 /
697 (double)modeline.vtotal));
698 else
699 XmuSnprintf(string, sizeof(string), "%dx%d",
700 modeline.hdisplay, modeline.vdisplay);
701 XtVaSetValues(text, XtNstring, string, NULL);
703 else {
704 XtVaSetValues(monitorb, XtNlabel, "", NULL);
705 XtSetSensitive(add, False);
706 XtVaSetValues(text, XtNstring, "", NULL);
710 /*ARGSUSED*/
711 void
712 VidmodeRestoreAction(Widget w, XEvent *event,
713 String *params, Cardinal *num_params)
715 if (vidtune != NULL) {
716 if (timeout != 0)
717 StopTestCallback(w, NULL, NULL);
718 else
719 RestoreCallback(w, NULL, NULL);
723 static void
724 UpdateSyncRates(Bool update)
726 if (modeline.htotal && modeline.vtotal) {
727 hsync_rate = (dot_clock * 1000) / modeline.htotal;
728 vsync_rate = (hsync_rate * 1000) / modeline.vtotal;
729 if (modeline.flags & V_INTERLACE)
730 vsync_rate *= 2;
731 else if (modeline.flags & V_DBLSCAN)
732 vsync_rate /= 2;
733 if (update) {
734 SetLabel(HSYNC, hsync_rate);
735 SetLabel(VSYNC, vsync_rate);
740 static void
741 SetLabel(int ident, int value)
743 Arg args[1];
744 char label[256];
746 if (ident == FLAGS) {
747 int len = 0;
749 *label = '\0';
750 if (value & V_PHSYNC)
751 len += XmuSnprintf(label, sizeof(label), "%s", "+hsync");
752 if (modeline.flags & V_NHSYNC)
753 len += XmuSnprintf(label + len, sizeof(label), "%s%s",
754 len ? " " : "", "-hsync");
755 if (value & V_PVSYNC)
756 len += XmuSnprintf(label + len, sizeof(label), "%s%s",
757 len ? " " : "", "+vsync");
758 if (value & V_NVSYNC)
759 len += XmuSnprintf(label + len, sizeof(label), "%s%s",
760 len ? " " : "", "-vsync");
761 if (value & V_INTERLACE)
762 len += XmuSnprintf(label + len, sizeof(label), "%s%s",
763 len ? " " : "", "interlace");
764 if (value & V_CSYNC)
765 len += XmuSnprintf(label + len, sizeof(label), "%s%s",
766 len ? " " : "", "composite");
767 if (value & V_PCSYNC)
768 len += XmuSnprintf(label + len, sizeof(label), "%s%s",
769 len ? " " : "", "+csync");
770 if (value & V_NCSYNC)
771 len += XmuSnprintf(label + len, sizeof(label), "%s%s",
772 len ? " " : "", "-csync");
773 if (value & V_DBLSCAN)
774 len += XmuSnprintf(label + len, sizeof(label), "%s%s",
775 len ? " " : "", "doublescan");
778 else if (ident == CLOCK || ident == HSYNC || ident == VSYNC)
779 XmuSnprintf(label, sizeof(label), "%6.2f", (float)value / 1000.0);
780 else
781 XmuSnprintf(label, sizeof(label), "%d", value);
783 XtSetArg(args[0], XtNlabel, label);
784 XtSetValues(values[ident], args, 1);
787 /*ARGSUSED*/
788 static void
789 StartAdjustMonitorCallback(Widget w, XtPointer client_data, XtPointer call_data)
791 repeater = w;
794 static void
795 AdjustMonitorCallback(Widget w, XtPointer client_data, XtPointer call_data)
797 if (repeater != w)
798 return;
799 switch ((long)client_data) {
800 case LEFT:
801 if (modeline.hsyncend + 4 < modeline.htotal) {
802 modeline.hsyncstart += 4;
803 modeline.hsyncend += 4;
804 SetLabel(HSYNCSTART, modeline.hsyncstart);
805 SetLabel(HSYNCEND, modeline.hsyncend);
807 else
808 XBell(XtDisplay(w), 80);
809 break;
810 case RIGHT:
811 if (modeline.hsyncstart - 4 > modeline.hdisplay) {
812 modeline.hsyncstart -= 4;
813 modeline.hsyncend -= 4;
814 SetLabel(HSYNCSTART, modeline.hsyncstart);
815 SetLabel(HSYNCEND, modeline.hsyncend);
817 else
818 XBell(XtDisplay(w), 80);
819 break;
820 case NARROWER:
821 modeline.htotal += 4;
822 SetLabel(HTOTAL, modeline.htotal);
823 UpdateSyncRates(True);
824 break;
825 case WIDER:
826 if (modeline.htotal - 4 > modeline.hsyncend) {
827 modeline.htotal -= 4;
828 SetLabel(HTOTAL, modeline.htotal);
829 UpdateSyncRates(True);
831 else
832 XBell(XtDisplay(w), 80);
833 break;
834 case UP:
835 if (modeline.vsyncend + 4 < modeline.vtotal) {
836 modeline.vsyncstart += 4;
837 modeline.vsyncend += 4;
838 SetLabel(VSYNCSTART, modeline.vsyncstart);
839 SetLabel(VSYNCEND, modeline.vsyncend);
841 else
842 XBell(XtDisplay(w), 80);
843 break;
844 case DOWN:
845 if (modeline.vsyncstart - 4 > modeline.vdisplay) {
846 modeline.vsyncstart -= 4;
847 modeline.vsyncend -= 4;
848 SetLabel(VSYNCSTART, modeline.vsyncstart);
849 SetLabel(VSYNCEND, modeline.vsyncend);
851 else
852 XBell(XtDisplay(w), 80);
853 break;
854 case SHORTER:
855 modeline.vtotal += 4;
856 SetLabel(VTOTAL, modeline.vtotal);
857 UpdateSyncRates(True);
858 break;
859 case TALLER:
860 if (modeline.vtotal - 4 > modeline.vsyncend) {
861 modeline.vtotal -= 4;
862 SetLabel(VTOTAL, modeline.vtotal);
863 UpdateSyncRates(True);
865 else
866 XBell(XtDisplay(w), 80);
867 break;
870 if (autoflag)
871 ApplyCallback(w, call_data, client_data);
874 /*ARGSUSED*/
875 static void
876 EndAdjustMonitorCallback(Widget w, XtPointer client_data, XtPointer call_data)
878 repeater = NULL;
881 static Bool
882 GetModeLine(Bool save)
884 if (XF86VidModeGetModeLine(XtDisplay(toplevel), vidtune->screen,
885 &dot_clock, &modeline)) {
886 if (save)
887 memcpy(&orig_modeline, &modeline, sizeof(XF86VidModeModeLine));
888 UpdateSyncRates(False);
889 return (True);
892 return (False);
895 static void
896 CleanUp(Display *display)
898 /* Make sure mode switching is not locked out at exit */
899 XF86VidModeLockModeSwitch(display, vidtune->screen, False);
900 XFlush(display);
903 static int
904 VidmodeError(Display *display, XErrorEvent *error)
906 if ((error->error_code >= ErrorBase &&
907 error->error_code < ErrorBase + XF86VidModeNumberErrors) ||
908 error->error_code == BadValue) {
909 hitError = 1;
911 else {
912 CleanUp(display);
913 if (XtErrorFunc)
914 (*XtErrorFunc)(display, error);
916 return (0);
919 /*ARGSUSED*/
920 static void
921 ApplyCallback(Widget w, XtPointer call_data, XtPointer client_data)
923 hitError = 0;
924 XF86VidModeModModeLine(XtDisplay(w), vidtune->screen, &modeline);
925 XSync(XtDisplay(w), False);
926 if (hitError) {
927 if (repeater != NULL) {
928 XtCallActionProc(repeater, "unset", NULL, NULL, 0);
929 XtCallActionProc(repeater, "stop", NULL, NULL, 0);
930 repeater = NULL;
932 XBell(XtDisplay(w), 80);
933 if (timeout)
934 StopTestCallback(w, NULL, NULL);
935 GetModeLine(False);
936 SetLabels();
940 /*ARGSUSED*/
941 static void
942 AutoCallback(Widget w, XtPointer call_data, XtPointer client_data)
944 autoflag = (Bool)(long)client_data;
945 XtSetSensitive(apply, !autoflag);
948 static void
949 RestoreCallback(Widget w, XtPointer call_data, XtPointer client_data)
951 memcpy(&modeline, &orig_modeline, sizeof(XF86VidModeModeLine));
952 if (autoflag)
953 ApplyCallback(w, call_data, client_data);
954 SetLabels();
957 static void
958 SelectCallback(Widget w, XtPointer call_data, XtPointer client_data)
960 XF86VidModeModeInfo *info = (XF86VidModeModeInfo*)call_data;
961 Arg args[1];
962 Bool result;
964 XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, False);
965 result = XF86VidModeSwitchToMode(XtDisplay(toplevel), vidtune->screen, info);
966 XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, True);
967 if (!result)
968 return;
970 XtSetArg(args[0], XtNlabel, XtName(w));
971 XtSetValues(mode, args, 1);
972 UpdateCallback(w, call_data, client_data);
975 static void
976 SwitchCallback(Widget w, XtPointer call_data, XtPointer client_data)
978 int direction = (long)call_data;
979 Arg args[1];
980 Bool result;
981 char label[32];
983 XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, False);
984 result = XF86VidModeSwitchMode(XtDisplay(toplevel), vidtune->screen,
985 direction);
986 XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, True);
987 if (!result)
988 return;
990 UpdateCallback(w, call_data, client_data);
992 if (modeline.htotal && modeline.vtotal)
993 XmuSnprintf(label, sizeof(label), "%dx%d @ %d Hz",
994 modeline.hdisplay, modeline.vdisplay,
995 (int)((double)dot_clock / (double)modeline.htotal * 1000.0 /
996 (double)modeline.vtotal));
997 else
998 XmuSnprintf(label, sizeof(label), "%dx%d",
999 modeline.hdisplay, modeline.vdisplay);
1000 XtSetArg(args[0], XtNlabel, label);
1001 XtSetValues(mode, args, 1);
1004 /*ARGSUSED*/
1005 static void
1006 UpdateCallback(Widget w, XtPointer call_data, XtPointer client_data)
1008 GetModeLine(True);
1009 SetLabels();
1010 SetLabelAndModeline();
1013 static void
1014 SetLabels(void)
1016 SetLabel(HSYNCSTART, modeline.hsyncstart);
1017 SetLabel(VSYNCSTART, modeline.vsyncstart);
1018 SetLabel(HSYNCEND, modeline.hsyncend);
1019 SetLabel(VSYNCEND, modeline.vsyncend);
1020 SetLabel(HTOTAL, modeline.htotal);
1021 SetLabel(VTOTAL, modeline.vtotal);
1022 SetLabel(FLAGS, modeline.flags);
1023 SetLabel(CLOCK, dot_clock);
1024 UpdateSyncRates(True);
1027 /*ARGSUSED*/
1028 static void
1029 ChangeScreenCallback(Widget w, XtPointer call_data, XtPointer client_data)
1031 Arg args[1];
1033 screenno = (long)call_data;
1034 if (screenno > computer.num_vidmodes || screenno < 0 ||
1035 vidtune == computer.vidmodes[screenno])
1036 return;
1038 XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, False);
1039 vidtune = computer.vidmodes[screenno];
1040 XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, True);
1041 UpdateCallback(w, call_data, client_data);
1042 GetModes();
1044 XtSetArg(args[0], XtNlabel, XtName(w));
1045 XtSetValues(screenb, args, 1);
1047 SetLabelAndModeline();
1050 /*ARGSUSED*/
1051 static void
1052 SelectMonitorCallback(Widget w, XtPointer call_data, XtPointer client_data)
1054 vidtune->monitor = (XF86ConfMonitorPtr)(call_data);
1055 SetLabelAndModeline();
1058 /*ARGSUSED*/
1059 static void
1060 AddVesaModeCallback(Widget w, XtPointer call_data, XtPointer client_data)
1062 xf86cfgVesaModeInfo *vesa = (xf86cfgVesaModeInfo*)call_data;
1063 XF86VidModeModeInfo mode;
1064 int num_infos = vidtune->num_infos;
1066 memcpy(&mode, &vesa->info, sizeof(XF86VidModeModeInfo));
1067 if (XF86VidModeAddModeLine(XtDisplay(toplevel), vidtune->screen,
1068 &vesa->info, &mode)) {
1069 XSync(XtDisplay(toplevel), False);
1070 GetModes();
1072 else {
1073 XBell(XtDisplayOfObject(w), 80);
1074 return;
1077 if (vidtune && num_infos == vidtune->num_infos) {
1078 /* XF86VidModeAddModeLine returned True, but no modeline was added */
1079 XBell(XtDisplayOfObject(w), 80);
1080 if (vidtune->monitor && AddMode()) {
1081 XF86ConfModeLinePtr mode;
1082 char label[256], *ptr, *str;
1084 XmuSnprintf(label, sizeof(label), "%s", vesa->ident);
1086 /* format mode name to not have spaces */
1087 ptr = strchr(label, ')');
1088 if (ptr)
1089 *++ptr = '\0';
1090 ptr = str = label;
1091 while (*ptr) {
1092 if (*ptr != ' ')
1093 *str++ = *ptr;
1094 ++ptr;
1096 *str = '\0';
1098 if (xf86findModeLine(label, vidtune->monitor->mon_modeline_lst)
1099 != NULL && !ForceAddMode())
1100 return;
1102 mode = (XF86ConfModeLinePtr)XtCalloc(1, sizeof(XF86ConfModeLineRec));
1103 mode->ml_identifier = XtNewString(label);
1104 mode->ml_clock = vesa->info.dotclock;
1105 mode->ml_hdisplay = vesa->info.hdisplay;
1106 mode->ml_hsyncstart = vesa->info.hsyncstart;
1107 mode->ml_hsyncend = vesa->info.hsyncend;
1108 mode->ml_htotal = vesa->info.htotal;
1109 mode->ml_vdisplay = vesa->info.vdisplay;
1110 mode->ml_vsyncstart = vesa->info.vsyncstart;
1111 mode->ml_vsyncend = vesa->info.vsyncend;
1112 mode->ml_vtotal = vesa->info.vtotal;
1113 /* mode->ml_vscan = ???;*/
1114 mode->ml_flags = vesa->info.flags;
1115 mode->ml_hskew = vesa->info.hskew;
1116 vidtune->monitor->mon_modeline_lst =
1117 xf86addModeLine(vidtune->monitor->mon_modeline_lst, mode);
1122 static void
1123 GetModes(void)
1125 int i;
1126 char label[32];
1127 Arg args[1];
1128 static char menuName[16];
1129 static int menuN;
1131 XFree(vidtune->infos);
1132 XF86VidModeGetAllModeLines(XtDisplay(toplevel), vidtune->screen,
1133 &vidtune->num_infos, &vidtune->infos);
1135 XmuSnprintf(menuName, sizeof(menuName), "menu%d", menuN);
1136 menuN = !menuN;
1137 if (menu)
1138 XtDestroyWidget(menu);
1139 menu = XtCreatePopupShell(menuName, simpleMenuWidgetClass, vtune, NULL, 0);
1140 XtVaSetValues(mode, XtNmenuName, menuName, NULL);
1141 for (i = 0; i < vidtune->num_infos; i++) {
1142 Widget sme;
1144 if ((double)vidtune->infos[i]->htotal &&
1145 (double)vidtune->infos[i]->vtotal)
1146 XmuSnprintf(label, sizeof(label), "%dx%d @ %d Hz",
1147 vidtune->infos[i]->hdisplay,
1148 vidtune->infos[i]->vdisplay,
1149 (int)((double)vidtune->infos[i]->dotclock /
1150 (double)vidtune->infos[i]->htotal * 1000.0 /
1151 (double)vidtune->infos[i]->vtotal));
1152 else
1153 XmuSnprintf(label, sizeof(label), "%dx%d",
1154 vidtune->infos[i]->hdisplay,
1155 vidtune->infos[i]->vdisplay);
1156 sme = XtCreateManagedWidget(label, smeBSBObjectClass, menu, NULL, 0);
1157 XtAddCallback(sme, XtNcallback, SelectCallback,
1158 (XtPointer)vidtune->infos[i]);
1161 if (modeline.htotal && modeline.vtotal)
1162 XmuSnprintf(label, sizeof(label), "%dx%d @ %d Hz",
1163 modeline.hdisplay, modeline.vdisplay,
1164 (int)((double)dot_clock / (double)modeline.htotal * 1000.0 /
1165 (double)modeline.vtotal));
1166 else
1167 XmuSnprintf(label, sizeof(label), "%dx%d",
1168 modeline.hdisplay, modeline.vdisplay);
1169 XtSetArg(args[0], XtNlabel, label);
1170 XtSetValues(mode, args, 1);
1173 static int do_force, asking_force;
1175 static void
1176 PopdownForce(Widget w, XtPointer user_data, XtPointer call_data)
1178 asking_force = 0;
1179 XtPopdown(forceshell);
1180 do_force = (long)user_data;
1183 static int
1184 ForceAddMode(void)
1186 if (forceshell == NULL) {
1187 Widget dialog;
1189 forceshell = XtCreatePopupShell("force", transientShellWidgetClass,
1190 toplevel, NULL, 0);
1191 dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass,
1192 forceshell, XtNvalue, NULL, NULL);
1193 XawDialogAddButton(dialog, "yes", PopdownForce, (XtPointer)True);
1194 XawDialogAddButton(dialog, "no", PopdownForce, (XtPointer)False);
1195 XtRealizeWidget(forceshell);
1196 XSetWMProtocols(DPY, XtWindow(forceshell), &wm_delete_window, 1);
1199 asking_force = 1;
1201 XtPopup(forceshell, XtGrabExclusive);
1202 while (asking_force)
1203 XtAppProcessEvent(XtWidgetToApplicationContext(forceshell), XtIMAll);
1205 return (do_force);
1208 static int do_add, asking_add;
1210 static void
1211 PopdownAdd(Widget w, XtPointer user_data, XtPointer call_data)
1213 asking_add = 0;
1214 XtPopdown(addshell);
1215 do_add = (long)user_data;
1218 void
1219 CancelAddModeAction(Widget w, XEvent *event,
1220 String *params, Cardinal *num_params)
1222 if (asking_force)
1223 PopdownForce(w, (XtPointer)False, NULL);
1224 else if (asking_add)
1225 PopdownAdd(w, (XtPointer)False, NULL);
1228 static int
1229 AddMode(void)
1231 if (addshell == NULL) {
1232 Widget dialog;
1234 addshell = XtCreatePopupShell("addMode", transientShellWidgetClass,
1235 toplevel, NULL, 0);
1236 dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass,
1237 addshell, XtNvalue, NULL, NULL);
1238 XawDialogAddButton(dialog, "yes", PopdownAdd, (XtPointer)True);
1239 XawDialogAddButton(dialog, "no", PopdownAdd, (XtPointer)False);
1240 XtRealizeWidget(addshell);
1241 XSetWMProtocols(DPY, XtWindow(addshell), &wm_delete_window, 1);
1244 asking_add = 1;
1246 XtPopup(addshell, XtGrabExclusive);
1247 while (asking_add)
1248 XtAppProcessEvent(XtWidgetToApplicationContext(addshell), XtIMAll);
1250 return (do_add);
1253 /*ARGSUSED*/
1254 static void
1255 AddModeCallback(Widget w, XtPointer call_data, XtPointer client_data)
1257 if (vidtune && vidtune->monitor) {
1258 char *label;
1259 Arg args[1];
1260 XF86ConfModeLinePtr mode;
1262 XtSetArg(args[0], XtNstring, &label);
1263 XtGetValues(text, args, 1);
1264 if (*label == '\0') {
1265 XBell(XtDisplay(w), 80);
1266 return;
1268 if (xf86findModeLine(label, vidtune->monitor->mon_modeline_lst)
1269 != NULL && !ForceAddMode())
1270 return;
1272 mode = (XF86ConfModeLinePtr)XtCalloc(1, sizeof(XF86ConfModeLineRec));
1273 mode->ml_identifier = XtNewString(label);
1274 mode->ml_clock = dot_clock;
1275 mode->ml_hdisplay = modeline.hdisplay;
1276 mode->ml_hsyncstart = modeline.hsyncstart;
1277 mode->ml_hsyncend = modeline.hsyncend;
1278 mode->ml_htotal = modeline.htotal;
1279 mode->ml_vdisplay = modeline.vdisplay;
1280 mode->ml_vsyncstart = modeline.vsyncstart;
1281 mode->ml_vsyncend = modeline.vsyncend;
1282 mode->ml_vtotal = modeline.vtotal;
1283 /* mode->ml_vscan = ???;*/
1284 mode->ml_flags = modeline.flags;
1285 mode->ml_hskew = modeline.hskew;
1286 vidtune->monitor->mon_modeline_lst =
1287 xf86addModeLine(vidtune->monitor->mon_modeline_lst, mode);
1289 else
1290 XBell(XtDisplay(w), 80);
1293 /*ARGSUSED*/
1294 static void
1295 StopTestCallback(Widget w, XtPointer call_data, XtPointer client_data)
1297 XtRemoveTimeOut(timeout);
1298 TestTimeout((XtPointer)w, NULL);
1301 /*ARGSUSED*/
1302 void
1303 CancelTestModeAction(Widget w, XEvent *event,
1304 String *params, Cardinal *num_params)
1306 StopTestCallback(w, NULL, NULL);
1309 static void
1310 TestTimeout(XtPointer client_data, XtIntervalId* id)
1312 XF86VidModeModeLine mode;
1314 XtPopdown(testshell);
1315 timeout = 0;
1316 memcpy(&mode, &modeline, sizeof(XF86VidModeModeLine));
1317 memcpy(&modeline, &orig_modeline, sizeof(XF86VidModeModeLine));
1318 ApplyCallback((Widget)client_data, NULL, NULL);
1319 /* if (hitError == 0)*/
1320 memcpy(&modeline, &mode, sizeof(XF86VidModeModeLine));
1321 SetLabels();
1324 static void
1325 TestCallback(Widget w, XtPointer call_data, XtPointer client_data)
1327 if (testshell == NULL) {
1328 Widget dialog;
1330 testshell = XtCreatePopupShell("test", transientShellWidgetClass,
1331 toplevel, NULL, 0);
1332 dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass,
1333 testshell, XtNvalue, NULL, NULL);
1334 XawDialogAddButton(dialog, "stop", StopTestCallback, NULL);
1335 XtRealizeWidget(testshell);
1336 XSetWMProtocols(DPY, XtWindow(testshell), &wm_delete_window, 1);
1339 XtPopup(testshell, XtGrabExclusive);
1341 XSync(XtDisplay(toplevel), False);
1342 timeout = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
1343 /* the timeout probably shoud be converted to a resource */
1344 4000, TestTimeout, (XtPointer)w);
1345 ApplyCallback(w, call_data, client_data);