2
* Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
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
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
27
* Author: Paulo C�sar Pereira de Andrade <pcpa@conectiva.com.br>
29
* $XFree86: xc/programs/Xserver/hw/xfree86/xf86cfg/vidmode.c,v 1.7 2001/07/07 23:00:43 paulo Exp $
33
* Most of the code here is based on the xvidtune code.
37
#include <X11/Xaw/Command.h>
38
#include <X11/Xaw/Form.h>
39
#include <X11/Xaw/Label.h>
40
#include <X11/Xaw/MenuButton.h>
41
#include <X11/Xaw/Repeater.h>
42
#include <X11/Shell.h>
43
#include <X11/Xaw/AsciiText.h>
44
#include <X11/Xaw/Dialog.h>
45
#include <X11/Xaw/SimpleMenP.h>
46
#include <X11/Xaw/SmeBSB.h>
47
#include <X11/Xaw/Toggle.h>
48
#include "xf86config.h"
50
#define V_FLAG_MASK 0x1FF
51
#define V_PHSYNC 0x001
52
#define V_NHSYNC 0x002
53
#define V_PVSYNC 0x004
54
#define V_NVSYNC 0x008
55
#define V_INTERLACE 0x010
56
#define V_DBLSCAN 0x020
58
#define V_PCSYNC 0x080
59
#define V_NCSYNC 0x100
91
XF86VidModeModeInfo info;
92
} xf86cfgVesaModeInfo;
97
static Bool GetModeLine(Bool);
98
static void StartAdjustMonitorCallback(Widget, XtPointer, XtPointer);
99
static void AdjustMonitorCallback(Widget, XtPointer, XtPointer);
100
static void EndAdjustMonitorCallback(Widget, XtPointer, XtPointer);
101
static void SetLabel(int, int);
102
static void UpdateSyncRates(Bool);
103
static int VidmodeError(Display*, XErrorEvent*);
104
static void CleanUp(Display*);
105
static void ApplyCallback(Widget, XtPointer, XtPointer);
106
static void AutoCallback(Widget, XtPointer, XtPointer);
107
static void RestoreCallback(Widget, XtPointer, XtPointer);
108
static void SelectCallback(Widget, XtPointer, XtPointer);
109
static void SelectMonitorCallback(Widget, XtPointer, XtPointer);
110
static void SwitchCallback(Widget, XtPointer, XtPointer);
111
static void SetLabels(void);
112
static void UpdateCallback(Widget, XtPointer, XtPointer);
113
static void ChangeScreenCallback(Widget, XtPointer, XtPointer);
114
static void SetLabelAndModeline(void);
115
static void AddVesaModeCallback(Widget, XtPointer, XtPointer);
116
static void GetModes(void);
117
static void AddModeCallback(Widget, XtPointer, XtPointer);
118
static void TestCallback(Widget, XtPointer, XtPointer);
119
static void TestTimeout(XtPointer, XtIntervalId*);
120
static void StopTestCallback(Widget, XtPointer, XtPointer);
121
static int ForceAddMode(void);
122
static int AddMode(void);
128
static Widget apply, automatic, restore, mode, menu, screenb, screenp;
129
static Bool autoflag;
130
static xf86cfgVidmode *vidtune;
131
static XF86VidModeModeLine modeline, orig_modeline;
132
static int dot_clock, hsync_rate, vsync_rate, hitError;
133
static Bool S3Specials;
134
static int invert_vclk, blank1, blank2, early_sc, screenno;
135
static int (*XtErrorFunc)(Display*, XErrorEvent*);
136
static Widget labels[VSYNC + 1], values[VSYNC + 1], repeater, monitor,
137
monitorb, add, text, vesab, vesap, forceshell, testshell, addshell;
138
static int MajorVersion, MinorVersion, EventBase, ErrorBase;
139
static XtIntervalId timeout;
141
/* The information bellow is extracted from
142
* xc/programs/Xserver/hw/xfree86/etc/vesamodes
143
* If that file is changed, please update the table bellow also. Or even
144
* better, write a script to generate the table.
146
static xf86cfgVesaModeInfo vesamodes[] = {
148
"640x350 @ 85Hz (VESA) hsync: 37.9kHz",
150
31500, 640, 672, 736, 832, 0, 350, 382, 385, 445,
155
"640x400 @ 85Hz (VESA) hsync: 37.9kHz",
157
31500, 640, 672, 736, 832, 0, 400, 401, 404, 445,
162
"720x400 @ 85Hz (VESA) hsync: 37.9kHz",
164
35500, 720, 756, 828, 936, 0, 400, 401, 404, 446,
169
"640x480 @ 60Hz (Industry standard) hsync: 31.5kHz",
171
25200, 640, 656, 752, 800, 0, 480, 490, 492, 525,
176
"640x480 @ 72Hz (VESA) hsync: 37.9kHz",
178
31500, 640, 664, 704, 832, 0, 480, 489, 491, 520,
183
"640x480 @ 75Hz (VESA) hsync: 37.5kHz",
185
31500, 640, 656, 720, 840, 0, 480, 481, 484, 500,
190
"640x480 @ 85Hz (VESA) hsync: 43.3kHz",
192
36000, 640, 696, 752, 832, 0, 480, 481, 484, 509,
197
"800x600 @ 56Hz (VESA) hsync: 35.2kHz",
199
36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625,
204
"800x600 @ 60Hz (VESA) hsync: 37.9kHz",
206
400000, 800, 840, 968, 1056, 0, 600, 601, 605, 628,
211
"800x600 @ 72Hz (VESA) hsync: 48.1kHz",
213
50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666,
218
"800x600 @ 75Hz (VESA) hsync: 46.9kHz",
220
49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625,
225
"800x600 @ 85Hz (VESA) hsync: 53.7kHz",
227
563000, 800, 832, 896, 1048, 0, 600, 601, 604, 631,
232
"1024x768i @ 43Hz (industry standard) hsync: 35.5kHz",
234
44900, 1024, 1032, 1208, 1264, 0, 768, 768, 776, 817,
235
V_PHSYNC | V_PVSYNC | V_INTERLACE
239
"1024x768 @ 60Hz (VESA) hsync: 48.4kHz",
241
65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806,
246
"1024x768 @ 70Hz (VESA) hsync: 56.5kHz",
248
75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806,
253
"1024x768 @ 75Hz (VESA) hsync: 60.0kHz",
255
78800, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800,
260
"1024x768 @ 85Hz (VESA) hsync: 68.7kHz",
262
94500, 1024, 1072, 1168, 1376, 0, 768, 769, 772, 808,
267
"1152x864 @ 75Hz (VESA) hsync: 67.5kHz",
269
108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900,
274
"1280x960 @ 60Hz (VESA) hsync: 60.0kHz",
276
108000, 1280, 1376, 1488, 1800, 0, 960, 961, 964, 1000,
281
"1280x960 @ 85Hz (VESA) hsync: 85.9kHz",
283
148500, 1280, 1344, 1504, 1728, 0, 960, 961, 964, 1011,
288
"1280x1024 @ 60Hz (VESA) hsync: 64.0kHz",
290
108000, 1280, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066,
295
"1280x1024 @ 75Hz (VESA) hsync: 80.0kHz",
297
135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066,
302
"1280x1024 @ 85Hz (VESA) hsync: 91.1kHz",
304
157500, 1280, 1344, 1504, 1728, 0, 1024, 1025, 1028, 1072,
309
"1600x1200 @ 60Hz (VESA) hsync: 75.0kHz",
311
162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
316
"1600x1200 @ 65Hz (VESA) hsync: 81.3kHz",
318
175500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
323
"1600x1200 @ 70Hz (VESA) hsync: 87.5kHz",
325
189000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
330
"1600x1200 @ 75Hz (VESA) hsync: 93.8kHz",
332
202500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
337
"1600x1200 @ 85Hz (VESA) hsync: 106.3kHz",
339
229500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250,
344
"1792x1344 @ 60Hz (VESA) hsync: 83.6kHz",
346
204800, 1792, 1920, 2120, 2448, 0, 1344, 1345, 1348, 1394,
351
"1792x1344 @ 75Hz (VESA) hsync: 106.3kHz",
353
261000, 1792, 1888, 2104, 2456, 0, 1344, 1345, 1348, 1417,
358
"1856x1392 @ 60Hz (VESA) hsync: 86.3kHz",
360
218300, 1856, 1952, 2176, 2528, 0, 1392, 1393, 1396, 1439,
365
"1856x1392 @ 75Hz (VESA) hsync: 112.5kHz",
367
288000, 1856, 1984, 2208, 2560, 0, 1392, 1393, 1396, 1500,
372
"1920x1440 @ 60Hz (VESA) hsync: 90.0kHz",
374
234000, 1920, 2048, 2256, 2600, 0, 1440, 1441, 1444, 1500,
379
"1920x1440 @ 75Hz (VESA) hsync: 112.5kHz",
381
297000, 1920, 2064, 2288, 2640, 0, 1440, 1441, 1444, 1500,
391
VideoModeInitialize(void)
394
char dispstr[128], *ptr, *tmp;
396
static char *names[] = {
410
static char *vnames[] = {
427
if (!XF86VidModeQueryVersion(XtDisplay(toplevel),
428
&MajorVersion, &MinorVersion)) {
429
fprintf(stderr, "Unable to query video extension version\n");
432
else if (!XF86VidModeQueryExtension(XtDisplay(toplevel),
433
&EventBase, &ErrorBase)) {
434
fprintf(stderr, "Unable to query video extension information\n");
437
else if (MajorVersion < MINMAJOR ||
438
(MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) {
440
"Xserver is running an old XFree86-VidModeExtension version"
441
" (%d.%d)\n", MajorVersion, MinorVersion);
442
fprintf(stderr, "Minimum required version is %d.%d\n",
447
InitializeVidmodes();
449
vtune = XtCreateWidget("vidtune", formWidgetClass,
452
vesab = XtVaCreateManagedWidget("vesaB", menuButtonWidgetClass, vtune,
453
XtNmenuName, "vesaP", NULL, 0);
454
vesap = XtCreatePopupShell("vesaP", simpleMenuWidgetClass, vtune, NULL, 0);
455
for (i = 0; i < sizeof(vesamodes) / sizeof(vesamodes[0]); i++) {
456
rep = XtCreateManagedWidget(vesamodes[i].ident, smeBSBObjectClass,
458
XtAddCallback(rep, XtNcallback, AddVesaModeCallback,
459
(XtPointer)&vesamodes[i]);
462
rep = XtCreateManagedWidget("prev", commandWidgetClass, vtune, NULL, 0);
463
XtAddCallback(rep, XtNcallback, SwitchCallback, (XtPointer)-1);
464
mode = XtCreateManagedWidget("mode", menuButtonWidgetClass, vtune, NULL, 0);
465
rep = XtCreateManagedWidget("next", commandWidgetClass, vtune, NULL, 0);
466
XtAddCallback(rep, XtNcallback, SwitchCallback, (XtPointer)1);
468
screenp = XtCreatePopupShell("screenP", simpleMenuWidgetClass, vtune,
471
XmuSnprintf(dispstr, sizeof(dispstr), "%s",
472
DisplayString(XtDisplay(toplevel)));
473
ptr = strrchr(dispstr, '.');
474
tmp = strrchr(dispstr, ':');
475
if (tmp != NULL && ptr != NULL && ptr > tmp)
478
for (i = 0; i < ScreenCount(XtDisplay(toplevel)); i++) {
481
XmuSnprintf(name, sizeof(name), "%s.%d", dispstr, i);
482
rep = XtCreateManagedWidget(name, smeBSBObjectClass, screenp,
484
XtAddCallback(rep, XtNcallback, ChangeScreenCallback,
487
screenb = XtVaCreateManagedWidget("screenB", menuButtonWidgetClass,
489
XtNmenuName, "screenP",
494
XtRealizeWidget(screenp);
496
rep = XtCreateManagedWidget("up", repeaterWidgetClass,
498
XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
499
XtAddCallback(rep, XtNcallback,
500
AdjustMonitorCallback, (XtPointer)UP);
501
XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
502
rep = XtCreateManagedWidget("left", repeaterWidgetClass,
504
XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
505
XtAddCallback(rep, XtNcallback,
506
AdjustMonitorCallback, (XtPointer)LEFT);
507
XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
508
XtCreateManagedWidget("monitor", simpleWidgetClass, vtune, NULL, 0);
509
rep = XtCreateManagedWidget("right", repeaterWidgetClass,
511
XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
512
XtAddCallback(rep, XtNcallback,
513
AdjustMonitorCallback, (XtPointer)RIGHT);
514
XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
515
rep = XtCreateManagedWidget("down", repeaterWidgetClass,
517
XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
518
XtAddCallback(rep, XtNcallback,
519
AdjustMonitorCallback, (XtPointer)DOWN);
520
XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
521
rep = XtCreateManagedWidget("wider", repeaterWidgetClass,
523
XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
524
XtAddCallback(rep, XtNcallback,
525
AdjustMonitorCallback, (XtPointer)WIDER);
526
XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
527
rep = XtCreateManagedWidget("narrower", repeaterWidgetClass,
529
XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
530
XtAddCallback(rep, XtNcallback,
531
AdjustMonitorCallback, (XtPointer)NARROWER);
532
XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
533
rep = XtCreateManagedWidget("shorter", repeaterWidgetClass,
535
XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
536
XtAddCallback(rep, XtNcallback,
537
AdjustMonitorCallback, (XtPointer)SHORTER);
538
XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
539
rep = XtCreateManagedWidget("taller", repeaterWidgetClass,
541
XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL);
542
XtAddCallback(rep, XtNcallback,
543
AdjustMonitorCallback, (XtPointer)TALLER);
544
XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL);
546
automatic = XtCreateManagedWidget("auto", toggleWidgetClass, vtune, NULL, 0);
547
XtAddCallback(automatic, XtNcallback, AutoCallback, NULL);
548
apply = XtCreateManagedWidget("apply", commandWidgetClass, vtune, NULL, 0);
549
XtAddCallback(apply, XtNcallback, ApplyCallback, NULL);
550
restore = XtCreateManagedWidget("restore", commandWidgetClass, vtune, NULL, 0);
551
XtAddCallback(restore, XtNcallback, RestoreCallback, NULL);
552
rep = XtCreateManagedWidget("update", commandWidgetClass, vtune, NULL, 0);
553
XtAddCallback(rep, XtNcallback, UpdateCallback, NULL);
554
rep = XtCreateManagedWidget("test", commandWidgetClass, vtune, NULL, 0);
555
XtAddCallback(rep, XtNcallback, TestCallback, NULL);
557
form = XtCreateManagedWidget("form", formWidgetClass, vtune, NULL, 0);
558
for (i = 2; i < VSYNC + 1; i++) {
559
labels[i] = XtCreateManagedWidget(names[i], labelWidgetClass,
561
values[i] = XtCreateManagedWidget(vnames[i], labelWidgetClass,
565
add = XtCreateManagedWidget("add", commandWidgetClass, vtune, NULL, 0);
566
XtAddCallback(add, XtNcallback, AddModeCallback, NULL);
567
XtCreateManagedWidget("addto", labelWidgetClass, vtune, NULL, 0);
568
monitorb = XtCreateManagedWidget("ident", menuButtonWidgetClass, vtune,
570
XtCreateManagedWidget("as", labelWidgetClass, vtune, NULL, 0);
571
text = XtVaCreateManagedWidget("text", asciiTextWidgetClass, vtune,
572
XtNeditType, XawtextEdit, NULL, 0);
574
XtRealizeWidget(vtune);
580
InitializeVidmodes(void)
583
Display *display = XtDisplay(toplevel);
585
computer.num_vidmodes = ScreenCount(display);
586
computer.vidmodes = (xf86cfgVidmode**)
587
XtMalloc(sizeof(xf86cfgVidmode*) * computer.num_vidmodes);
588
for (i = 0; i < computer.num_vidmodes; i++) {
590
computer.vidmodes[i] = (xf86cfgVidmode*)
591
XtCalloc(1, sizeof(xf86cfgVidmode));
592
computer.vidmodes[i]->screen = i;
597
VideoModeConfigureStart(void)
599
vidtune = computer.vidmodes[screenno];
601
XtSetSensitive(vtune, vidtune != NULL);
602
if (!XtIsManaged(vtune))
603
XtManageChild(vtune);
606
if (vidtune != NULL) {
609
XF86ConfMonitorPtr mon;
610
static char menuName[16];
613
XtErrorFunc = XSetErrorHandler(VidmodeError);
614
XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, True);
619
XtSetArg(args[0], XtNstate, &state);
620
XtGetValues(automatic, args, 1);
621
XtSetSensitive(apply, !state);
625
XtDestroyWidget(monitor);
626
XmuSnprintf(menuName, sizeof(menuName), "menuP%d", menuN);
628
monitor = XtCreatePopupShell(menuName, simpleMenuWidgetClass,
630
XtVaSetValues(monitorb, XtNmenuName, menuName, NULL, 0);
632
mon = XF86Config->conf_monitor_lst;
633
while (mon != NULL) {
634
Widget sme = XtCreateManagedWidget(mon->mon_identifier,
637
XtAddCallback(sme, XtNcallback,
638
SelectMonitorCallback, (XtPointer)mon);
640
/* guess the monitor at a given screen and/or
641
* updates configuration if a monitor was removed from the
644
if (XF86Config->conf_layout_lst) {
645
XF86ConfAdjacencyPtr adj = XF86Config->conf_layout_lst->
648
while (adj != NULL) {
649
if (adj->adj_screen != NULL) {
650
if (adj->adj_screen->scrn_monitor == mon &&
651
adj->adj_scrnum >= 0 &&
652
adj->adj_scrnum < ScreenCount(XtDisplay(toplevel))) {
653
if (computer.vidmodes[adj->adj_scrnum]->monitor ==
654
NULL || computer.vidmodes[adj->adj_scrnum]->
655
monitor == adj->adj_screen->scrn_monitor) {
656
computer.vidmodes[adj->adj_scrnum]->monitor =
657
adj->adj_screen->scrn_monitor;
661
computer.vidmodes[adj->adj_scrnum]->monitor =
665
adj = (XF86ConfAdjacencyPtr)(adj->list.next);
668
mon = (XF86ConfMonitorPtr)(mon->list.next);
670
SetLabelAndModeline();
675
VideoModeConfigureEnd(void)
677
XtUnmapWidget(vtune);
678
if (vidtune != NULL) {
679
XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, False);
680
XSetErrorHandler(XtErrorFunc);
686
SetLabelAndModeline(void)
688
if (vidtune->monitor != NULL) {
691
XtVaSetValues(monitorb, XtNlabel,
692
vidtune->monitor->mon_identifier, NULL);
693
XtSetSensitive(add, True);
695
if (modeline.htotal && modeline.vtotal)
696
XmuSnprintf(string, sizeof(string), "%dx%d@%d",
697
modeline.hdisplay, modeline.vdisplay,
698
(int)((double)dot_clock / (double)modeline.htotal * 1000.0 /
699
(double)modeline.vtotal));
701
XmuSnprintf(string, sizeof(string), "%dx%d",
702
modeline.hdisplay, modeline.vdisplay);
703
XtVaSetValues(text, XtNstring, string, NULL);
706
XtVaSetValues(monitorb, XtNlabel, "", NULL);
707
XtSetSensitive(add, False);
708
XtVaSetValues(text, XtNstring, "", NULL);
714
VidmodeRestoreAction(Widget w, XEvent *event,
715
String *params, Cardinal *num_params)
717
if (vidtune != NULL) {
719
StopTestCallback(w, NULL, NULL);
721
RestoreCallback(w, NULL, NULL);
726
UpdateSyncRates(Bool update)
728
if (modeline.htotal && modeline.vtotal) {
729
hsync_rate = (dot_clock * 1000) / modeline.htotal;
730
vsync_rate = (hsync_rate * 1000) / modeline.vtotal;
731
if (modeline.flags & V_INTERLACE)
733
else if (modeline.flags & V_DBLSCAN)
736
SetLabel(HSYNC, hsync_rate);
737
SetLabel(VSYNC, vsync_rate);
743
SetLabel(int ident, int value)
748
if (ident == FLAGS) {
752
if (value & V_PHSYNC)
753
len += XmuSnprintf(label, sizeof(label), "%s", "+hsync");
754
if (modeline.flags & V_NHSYNC)
755
len += XmuSnprintf(label + len, sizeof(label), "%s%s",
756
len ? " " : "", "-hsync");
757
if (value & V_PVSYNC)
758
len += XmuSnprintf(label + len, sizeof(label), "%s%s",
759
len ? " " : "", "+vsync");
760
if (value & V_NVSYNC)
761
len += XmuSnprintf(label + len, sizeof(label), "%s%s",
762
len ? " " : "", "-vsync");
763
if (value & V_INTERLACE)
764
len += XmuSnprintf(label + len, sizeof(label), "%s%s",
765
len ? " " : "", "interlace");
767
len += XmuSnprintf(label + len, sizeof(label), "%s%s",
768
len ? " " : "", "composite");
769
if (value & V_PCSYNC)
770
len += XmuSnprintf(label + len, sizeof(label), "%s%s",
771
len ? " " : "", "+csync");
772
if (value & V_NCSYNC)
773
len += XmuSnprintf(label + len, sizeof(label), "%s%s",
774
len ? " " : "", "-csync");
775
if (value & V_DBLSCAN)
776
len += XmuSnprintf(label + len, sizeof(label), "%s%s",
777
len ? " " : "", "doublescan");
780
else if (ident == CLOCK || ident == HSYNC || ident == VSYNC)
781
XmuSnprintf(label, sizeof(label), "%6.2f", (float)value / 1000.0);
783
XmuSnprintf(label, sizeof(label), "%d", value);
785
XtSetArg(args[0], XtNlabel, label);
786
XtSetValues(values[ident], args, 1);
791
StartAdjustMonitorCallback(Widget w, XtPointer client_data, XtPointer call_data)
797
AdjustMonitorCallback(Widget w, XtPointer client_data, XtPointer call_data)
801
switch ((long)client_data) {
803
if (modeline.hsyncend + 4 < modeline.htotal) {
804
modeline.hsyncstart += 4;
805
modeline.hsyncend += 4;
806
SetLabel(HSYNCSTART, modeline.hsyncstart);
807
SetLabel(HSYNCEND, modeline.hsyncend);
810
XBell(XtDisplay(w), 80);
813
if (modeline.hsyncstart - 4 > modeline.hdisplay) {
814
modeline.hsyncstart -= 4;
815
modeline.hsyncend -= 4;
816
SetLabel(HSYNCSTART, modeline.hsyncstart);
817
SetLabel(HSYNCEND, modeline.hsyncend);
820
XBell(XtDisplay(w), 80);
823
modeline.htotal += 4;
824
SetLabel(HTOTAL, modeline.htotal);
825
UpdateSyncRates(True);
828
if (modeline.htotal - 4 > modeline.hsyncend) {
829
modeline.htotal -= 4;
830
SetLabel(HTOTAL, modeline.htotal);
831
UpdateSyncRates(True);
834
XBell(XtDisplay(w), 80);
837
if (modeline.vsyncend + 4 < modeline.vtotal) {
838
modeline.vsyncstart += 4;
839
modeline.vsyncend += 4;
840
SetLabel(VSYNCSTART, modeline.vsyncstart);
841
SetLabel(VSYNCEND, modeline.vsyncend);
844
XBell(XtDisplay(w), 80);
847
if (modeline.vsyncstart - 4 > modeline.vdisplay) {
848
modeline.vsyncstart -= 4;
849
modeline.vsyncend -= 4;
850
SetLabel(VSYNCSTART, modeline.vsyncstart);
851
SetLabel(VSYNCEND, modeline.vsyncend);
854
XBell(XtDisplay(w), 80);
857
modeline.vtotal += 4;
858
SetLabel(VTOTAL, modeline.vtotal);
859
UpdateSyncRates(True);
862
if (modeline.vtotal - 4 > modeline.vsyncend) {
863
modeline.vtotal -= 4;
864
SetLabel(VTOTAL, modeline.vtotal);
865
UpdateSyncRates(True);
868
XBell(XtDisplay(w), 80);
873
ApplyCallback(w, call_data, client_data);
878
EndAdjustMonitorCallback(Widget w, XtPointer client_data, XtPointer call_data)
884
GetModeLine(Bool save)
886
if (XF86VidModeGetModeLine(XtDisplay(toplevel), vidtune->screen,
887
&dot_clock, &modeline)) {
889
memcpy(&orig_modeline, &modeline, sizeof(XF86VidModeModeLine));
890
UpdateSyncRates(False);
891
if (modeline.privsize != 0 && modeline.private != NULL) {
893
invert_vclk = modeline.private[1];
894
blank1 = modeline.private[2] & 7;
895
blank2 = (modeline.private[2] >> 4) & 7;
896
early_sc = modeline.private[3];
907
CleanUp(Display *display)
909
/* Make sure mode switching is not locked out at exit */
910
XF86VidModeLockModeSwitch(display, vidtune->screen, False);
915
VidmodeError(Display *display, XErrorEvent *error)
917
if ((error->error_code >= ErrorBase &&
918
error->error_code < ErrorBase + XF86VidModeNumberErrors) ||
919
error->error_code == BadValue) {
925
(*XtErrorFunc)(display, error);
932
ApplyCallback(Widget w, XtPointer call_data, XtPointer client_data)
935
XF86VidModeModModeLine(XtDisplay(w), vidtune->screen, &modeline);
936
XSync(XtDisplay(w), False);
938
if (repeater != NULL) {
939
XtCallActionProc(repeater, "unset", NULL, NULL, 0);
940
XtCallActionProc(repeater, "stop", NULL, NULL, 0);
943
XBell(XtDisplay(w), 80);
945
StopTestCallback(w, NULL, NULL);
953
AutoCallback(Widget w, XtPointer call_data, XtPointer client_data)
955
autoflag = (Bool)(long)client_data;
956
XtSetSensitive(apply, !autoflag);
960
RestoreCallback(Widget w, XtPointer call_data, XtPointer client_data)
962
memcpy(&modeline, &orig_modeline, sizeof(XF86VidModeModeLine));
964
ApplyCallback(w, call_data, client_data);
969
SelectCallback(Widget w, XtPointer call_data, XtPointer client_data)
971
XF86VidModeModeInfo *info = (XF86VidModeModeInfo*)call_data;
975
XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, False);
976
result = XF86VidModeSwitchToMode(XtDisplay(toplevel), vidtune->screen, info);
977
XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, True);
981
XtSetArg(args[0], XtNlabel, XtName(w));
982
XtSetValues(mode, args, 1);
983
UpdateCallback(w, call_data, client_data);
987
SwitchCallback(Widget w, XtPointer call_data, XtPointer client_data)
989
int direction = (long)call_data;
994
XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, False);
995
result = XF86VidModeSwitchMode(XtDisplay(toplevel), vidtune->screen,
997
XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, True);
1001
UpdateCallback(w, call_data, client_data);
1003
if (modeline.htotal && modeline.vtotal)
1004
XmuSnprintf(label, sizeof(label), "%dx%d @ %d Hz",
1005
modeline.hdisplay, modeline.vdisplay,
1006
(int)((double)dot_clock / (double)modeline.htotal * 1000.0 /
1007
(double)modeline.vtotal));
1009
XmuSnprintf(label, sizeof(label), "%dx%d",
1010
modeline.hdisplay, modeline.vdisplay);
1011
XtSetArg(args[0], XtNlabel, label);
1012
XtSetValues(mode, args, 1);
1017
UpdateCallback(Widget w, XtPointer call_data, XtPointer client_data)
1021
SetLabelAndModeline();
1027
SetLabel(HSYNCSTART, modeline.hsyncstart);
1028
SetLabel(VSYNCSTART, modeline.vsyncstart);
1029
SetLabel(HSYNCEND, modeline.hsyncend);
1030
SetLabel(VSYNCEND, modeline.vsyncend);
1031
SetLabel(HTOTAL, modeline.htotal);
1032
SetLabel(VTOTAL, modeline.vtotal);
1033
SetLabel(FLAGS, modeline.flags);
1034
SetLabel(CLOCK, dot_clock);
1035
UpdateSyncRates(True);
1040
ChangeScreenCallback(Widget w, XtPointer call_data, XtPointer client_data)
1044
screenno = (long)call_data;
1045
if (screenno > computer.num_vidmodes || screenno < 0 ||
1046
vidtune == computer.vidmodes[screenno])
1049
XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, False);
1050
vidtune = computer.vidmodes[screenno];
1051
XF86VidModeLockModeSwitch(XtDisplay(toplevel), vidtune->screen, True);
1052
UpdateCallback(w, call_data, client_data);
1055
XtSetArg(args[0], XtNlabel, XtName(w));
1056
XtSetValues(screenb, args, 1);
1058
SetLabelAndModeline();
1063
SelectMonitorCallback(Widget w, XtPointer call_data, XtPointer client_data)
1065
vidtune->monitor = (XF86ConfMonitorPtr)(call_data);
1066
SetLabelAndModeline();
1071
AddVesaModeCallback(Widget w, XtPointer call_data, XtPointer client_data)
1073
xf86cfgVesaModeInfo *vesa = (xf86cfgVesaModeInfo*)call_data;
1074
XF86VidModeModeInfo mode;
1075
int num_infos = vidtune->num_infos;
1077
memcpy(&mode, &vesa->info, sizeof(XF86VidModeModeInfo));
1078
if (XF86VidModeAddModeLine(XtDisplay(toplevel), vidtune->screen,
1079
&vesa->info, &mode)) {
1080
XSync(XtDisplay(toplevel), False);
1084
XBell(XtDisplayOfObject(w), 80);
1088
if (vidtune && num_infos == vidtune->num_infos) {
1089
/* XF86VidModeAddModeLine returned True, but no modeline was added */
1090
XBell(XtDisplayOfObject(w), 80);
1091
if (vidtune->monitor && AddMode()) {
1092
XF86ConfModeLinePtr mode;
1093
char label[256], *ptr, *str;
1095
XmuSnprintf(label, sizeof(label), "%s", vesa->ident);
1097
/* format mode name to not have spaces */
1098
ptr = strchr(label, ')');
1109
if (xf86findModeLine(label, vidtune->monitor->mon_modeline_lst)
1110
!= NULL && !ForceAddMode())
1113
mode = (XF86ConfModeLinePtr)XtCalloc(1, sizeof(XF86ConfModeLineRec));
1114
mode->ml_identifier = XtNewString(label);
1115
mode->ml_clock = vesa->info.dotclock;
1116
mode->ml_hdisplay = vesa->info.hdisplay;
1117
mode->ml_hsyncstart = vesa->info.hsyncstart;
1118
mode->ml_hsyncend = vesa->info.hsyncend;
1119
mode->ml_htotal = vesa->info.htotal;
1120
mode->ml_vdisplay = vesa->info.vdisplay;
1121
mode->ml_vsyncstart = vesa->info.vsyncstart;
1122
mode->ml_vsyncend = vesa->info.vsyncend;
1123
mode->ml_vtotal = vesa->info.vtotal;
1124
/* mode->ml_vscan = ???;*/
1125
mode->ml_flags = vesa->info.flags;
1126
mode->ml_hskew = vesa->info.hskew;
1127
vidtune->monitor->mon_modeline_lst =
1128
xf86addModeLine(vidtune->monitor->mon_modeline_lst, mode);
1139
static char menuName[16];
1142
XFree(vidtune->infos);
1143
XF86VidModeGetAllModeLines(XtDisplay(toplevel), vidtune->screen,
1144
&vidtune->num_infos, &vidtune->infos);
1146
XmuSnprintf(menuName, sizeof(menuName), "menu%d", menuN);
1149
XtDestroyWidget(menu);
1150
menu = XtCreatePopupShell(menuName, simpleMenuWidgetClass, vtune, NULL, 0);
1151
XtVaSetValues(mode, XtNmenuName, menuName, NULL, 0);
1152
for (i = 0; i < vidtune->num_infos; i++) {
1155
if ((double)vidtune->infos[i]->htotal &&
1156
(double)vidtune->infos[i]->vtotal)
1157
XmuSnprintf(label, sizeof(label), "%dx%d @ %d Hz",
1158
vidtune->infos[i]->hdisplay,
1159
vidtune->infos[i]->vdisplay,
1160
(int)((double)vidtune->infos[i]->dotclock /
1161
(double)vidtune->infos[i]->htotal * 1000.0 /
1162
(double)vidtune->infos[i]->vtotal));
1164
XmuSnprintf(label, sizeof(label), "%dx%d",
1165
vidtune->infos[i]->hdisplay,
1166
vidtune->infos[i]->vdisplay);
1167
sme = XtCreateManagedWidget(label, smeBSBObjectClass, menu, NULL, 0);
1168
XtAddCallback(sme, XtNcallback, SelectCallback,
1169
(XtPointer)vidtune->infos[i]);
1172
if (modeline.htotal && modeline.vtotal)
1173
XmuSnprintf(label, sizeof(label), "%dx%d @ %d Hz",
1174
modeline.hdisplay, modeline.vdisplay,
1175
(int)((double)dot_clock / (double)modeline.htotal * 1000.0 /
1176
(double)modeline.vtotal));
1178
XmuSnprintf(label, sizeof(label), "%dx%d",
1179
modeline.hdisplay, modeline.vdisplay);
1180
XtSetArg(args[0], XtNlabel, label);
1181
XtSetValues(mode, args, 1);
1184
static int do_force, asking_force;
1187
PopdownForce(Widget w, XtPointer user_data, XtPointer call_data)
1190
XtPopdown(forceshell);
1191
do_force = (long)user_data;
1197
if (forceshell == NULL) {
1200
forceshell = XtCreatePopupShell("force", transientShellWidgetClass,
1202
dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass,
1203
forceshell, XtNvalue, NULL, NULL, 0);
1204
XawDialogAddButton(dialog, "yes", PopdownForce, (XtPointer)True);
1205
XawDialogAddButton(dialog, "no", PopdownForce, (XtPointer)False);
1206
XtRealizeWidget(forceshell);
1207
XSetWMProtocols(DPY, XtWindow(forceshell), &wm_delete_window, 1);
1212
XtPopup(forceshell, XtGrabExclusive);
1213
while (asking_force)
1214
XtAppProcessEvent(XtWidgetToApplicationContext(forceshell), XtIMAll);
1219
static int do_add, asking_add;
1222
PopdownAdd(Widget w, XtPointer user_data, XtPointer call_data)
1225
XtPopdown(addshell);
1226
do_add = (long)user_data;
1230
CancelAddModeAction(Widget w, XEvent *event,
1231
String *params, Cardinal *num_params)
1234
PopdownForce(w, (XtPointer)False, NULL);
1235
else if (asking_add)
1236
PopdownAdd(w, (XtPointer)False, NULL);
1242
if (addshell == NULL) {
1245
addshell = XtCreatePopupShell("addMode", transientShellWidgetClass,
1247
dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass,
1248
addshell, XtNvalue, NULL, NULL, 0);
1249
XawDialogAddButton(dialog, "yes", PopdownAdd, (XtPointer)True);
1250
XawDialogAddButton(dialog, "no", PopdownAdd, (XtPointer)False);
1251
XtRealizeWidget(addshell);
1252
XSetWMProtocols(DPY, XtWindow(addshell), &wm_delete_window, 1);
1257
XtPopup(addshell, XtGrabExclusive);
1259
XtAppProcessEvent(XtWidgetToApplicationContext(addshell), XtIMAll);
1266
AddModeCallback(Widget w, XtPointer call_data, XtPointer client_data)
1268
if (vidtune && vidtune->monitor) {
1271
XF86ConfModeLinePtr mode;
1273
XtSetArg(args[0], XtNstring, &label);
1274
XtGetValues(text, args, 1);
1275
if (*label == '\0') {
1276
XBell(XtDisplay(w), 80);
1279
if (xf86findModeLine(label, vidtune->monitor->mon_modeline_lst)
1280
!= NULL && !ForceAddMode())
1283
mode = (XF86ConfModeLinePtr)XtCalloc(1, sizeof(XF86ConfModeLineRec));
1284
mode->ml_identifier = XtNewString(label);
1285
mode->ml_clock = dot_clock;
1286
mode->ml_hdisplay = modeline.hdisplay;
1287
mode->ml_hsyncstart = modeline.hsyncstart;
1288
mode->ml_hsyncend = modeline.hsyncend;
1289
mode->ml_htotal = modeline.htotal;
1290
mode->ml_vdisplay = modeline.vdisplay;
1291
mode->ml_vsyncstart = modeline.vsyncstart;
1292
mode->ml_vsyncend = modeline.vsyncend;
1293
mode->ml_vtotal = modeline.vtotal;
1294
/* mode->ml_vscan = ???;*/
1295
mode->ml_flags = modeline.flags;
1296
mode->ml_hskew = modeline.hskew;
1297
vidtune->monitor->mon_modeline_lst =
1298
xf86addModeLine(vidtune->monitor->mon_modeline_lst, mode);
1301
XBell(XtDisplay(w), 80);
1306
StopTestCallback(Widget w, XtPointer call_data, XtPointer client_data)
1308
XtRemoveTimeOut(timeout);
1309
TestTimeout((XtPointer)w, NULL);
1314
CancelTestModeAction(Widget w, XEvent *event,
1315
String *params, Cardinal *num_params)
1317
StopTestCallback(w, NULL, NULL);
1321
TestTimeout(XtPointer client_data, XtIntervalId* id)
1323
XF86VidModeModeLine mode;
1325
XtPopdown(testshell);
1327
memcpy(&mode, &modeline, sizeof(XF86VidModeModeLine));
1328
memcpy(&modeline, &orig_modeline, sizeof(XF86VidModeModeLine));
1329
ApplyCallback((Widget)client_data, NULL, NULL);
1330
/* if (hitError == 0)*/
1331
memcpy(&modeline, &mode, sizeof(XF86VidModeModeLine));
1336
TestCallback(Widget w, XtPointer call_data, XtPointer client_data)
1338
if (testshell == NULL) {
1341
testshell = XtCreatePopupShell("test", transientShellWidgetClass,
1343
dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass,
1344
testshell, XtNvalue, NULL, NULL, 0);
1345
XawDialogAddButton(dialog, "stop", StopTestCallback, NULL);
1346
XtRealizeWidget(testshell);
1347
XSetWMProtocols(DPY, XtWindow(testshell), &wm_delete_window, 1);
1350
XtPopup(testshell, XtGrabExclusive);
1352
XSync(XtDisplay(toplevel), False);
1353
timeout = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
1354
/* the timeout probably shoud be converted to a resource */
1355
4000, TestTimeout, (XtPointer)w);
1356
ApplyCallback(w, call_data, client_data);