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>
31 #include "xf86config.h"
32 #include "monitor-cfg.h"
34 #include <X11/extensions/xf86vmode.h>
35 #include <X11/Xaw/Form.h>
36 #include <X11/Xaw/Simple.h>
39 #include <X11/Xaw/Label.h>
40 #include <X11/Xaw/AsciiText.h>
41 #include <X11/Xaw/List.h>
42 #include <X11/Xaw/MenuButton.h>
43 #include <X11/Xaw/Viewport.h>
44 #include <X11/Xaw/SimpleMenu.h>
45 #include <X11/Xaw/SmeBSB.h>
50 static Bool
MonitorConfigCheck(void);
51 static void MonitorHsyncCallback(Widget
, XtPointer
, XtPointer
);
52 static void MonitorVsyncCallback(Widget
, XtPointer
, XtPointer
);
53 static void MonitorSelectCardCallback(Widget
, XtPointer
, XtPointer
);
55 extern void DrawCables(void);
60 static char *hmodes
[] = {
61 "Standard VGA, 640x480 @ 60 Hz",
62 "Super VGA, 800x600 @ 56 Hz",
63 "1024x768 @ 87 Hz int. (no 800x600)",
64 "1024x768 @ 87 Hz int., 800x600 @ 56 Hz",
65 "800x600 @ 60 Hz, 640x480 @ 72 Hz",
66 "1024x768 @ 60 Hz, 800x600 @ 72 Hz",
67 "High Frequency SVGA, 1024x768 @ 70 Hz",
68 "Monitor that can do 1280x1024 @ 60 Hz",
69 "Monitor that can do 1280x1024 @ 74 Hz",
70 "Monitor that can do 1280x1024 @ 76 Hz",
71 "Monitor that can do 1280x1024 @ 85 Hz",
72 "Monitor that can do 1600x1200 @ 85 Hz",
73 "Monitor that can do 1920x1440 @ 85 Hz",
74 "Monitor that can do 2048x1536 @ 85 Hz"
77 static char *hmodes_trans
[] = {
94 static char *vmodes
[] = { "50 - 70", "50 - 90", "50 - 100", "40 - 150", };
97 static Widget hsync
, vsync
, hlist
, vlist
, cmenu
;
99 static parser_range mon_hsync
[CONF_MAX_HSYNC
];
100 static parser_range mon_vrefresh
[CONF_MAX_VREFRESH
];
101 static int mon_n_hsync
, mon_n_vrefresh
;
102 static XF86ConfDevicePtr oldcard
, card
;
103 static XF86ConfMonitorPtr current_monitor
;
109 MonitorConfig(XtPointer conf
)
111 XF86ConfMonitorPtr monitor
= (XF86ConfMonitorPtr
)conf
;
112 char monitor_name
[48];
115 current_monitor
= monitor
;
117 xf86info
.cur_list
= MONITOR
;
118 XtSetSensitive(back
, xf86info
.lists
[MONITOR
].cur_function
> 0);
119 XtSetSensitive(next
, xf86info
.lists
[MONITOR
].cur_function
<
120 xf86info
.lists
[MONITOR
].num_functions
- 1);
121 (xf86info
.lists
[MONITOR
].functions
[xf86info
.lists
[MONITOR
].cur_function
])
124 XawListUnhighlight(hlist
);
125 XawListUnhighlight(vlist
);
127 if (monitor
!= NULL
) {
128 XF86ConfScreenPtr screen
= XF86Config
->conf_screen_lst
;
129 char str
[PARSER_RANGE_SIZE
];
131 XtSetArg(args
[0], XtNstring
, monitor
->mon_identifier
);
132 XtSetValues(ident_widget
, args
, 1);
134 while (screen
!= NULL
) {
135 if (screen
->scrn_monitor
== monitor
)
138 screen
= (XF86ConfScreenPtr
)(screen
->list
.next
);
140 if (screen
!= NULL
) {
141 oldcard
= card
= screen
->scrn_device
;
142 XtSetArg(args
[0], XtNlabel
, card
->dev_identifier
);
145 oldcard
= card
= NULL
;
146 XtSetArg(args
[0], XtNlabel
, "");
148 XtSetValues(cmenu
, args
, 1);
150 mon_n_hsync
= monitor
->mon_n_hsync
;
151 memcpy(mon_hsync
, monitor
->mon_hsync
,
152 sizeof(parser_range
) * mon_n_hsync
);
154 parser_range_to_string(str
, mon_hsync
, mon_n_hsync
);
155 XtSetArg(args
[0], XtNstring
, str
);
156 XtSetValues(hsync
, args
, 1);
158 mon_n_vrefresh
= monitor
->mon_n_vrefresh
;
159 memcpy(mon_vrefresh
, monitor
->mon_vrefresh
,
160 sizeof(parser_range
) * mon_n_vrefresh
);
162 parser_range_to_string(str
, mon_vrefresh
, mon_n_vrefresh
);
163 XtSetArg(args
[0], XtNstring
, str
);
164 XtSetValues(vsync
, args
, 1);
167 XF86ConfMonitorPtr monitor
= XF86Config
->conf_monitor_lst
;
170 oldcard
= card
= NULL
;
171 while (monitor
!= NULL
) {
173 monitor
= (XF86ConfMonitorPtr
)(monitor
->list
.next
);
176 XmuSnprintf(monitor_name
, sizeof(monitor_name
),
177 "Monitor%d", nmonitors
);
179 } while (xf86findMonitor(monitor_name
,
180 XF86Config
->conf_monitor_lst
));
182 XtSetArg(args
[0], XtNstring
, monitor_name
);
183 XtSetValues(ident_widget
, args
, 1);
185 XtSetArg(args
[0], XtNstring
, "");
186 XtSetValues(hsync
, args
, 1);
187 XtSetValues(vsync
, args
, 1);
189 XtSetArg(args
[0], XtNlabel
, "");
190 XtSetValues(cmenu
, args
, 1);
193 if (ConfigLoop(MonitorConfigCheck
) == True
) {
194 if (monitor
== NULL
) {
195 monitor
= (XF86ConfMonitorPtr
)
196 XtCalloc(1, sizeof(XF86ConfMonitorRec
));
197 monitor
->mon_identifier
= XtNewString(ident_string
);
200 memcpy(monitor
->mon_hsync
, mon_hsync
, sizeof(parser_range
) *
201 (monitor
->mon_n_hsync
= mon_n_hsync
));
202 memcpy(monitor
->mon_vrefresh
, mon_vrefresh
, sizeof(parser_range
) *
203 (monitor
->mon_n_vrefresh
= mon_n_vrefresh
));
205 if (strcasecmp(monitor
->mon_identifier
, ident_string
))
206 xf86renameMonitor(XF86Config
, monitor
, ident_string
);
208 if (oldcard
!= card
) {
211 for (i
= 0; i
< computer
.num_devices
; i
++)
212 if (computer
.devices
[i
]->widget
== config
)
214 if (computer
.devices
[i
]->config
== NULL
)
215 XF86Config
->conf_monitor_lst
=
216 xf86addMonitor(XF86Config
->conf_monitor_lst
,
218 computer
.devices
[i
]->config
= (XtPointer
)monitor
;
219 ChangeScreen(monitor
, monitor
, card
, oldcard
);
230 MonitorConfigCheck(void)
234 XF86ConfMonitorPtr monitor
= XF86Config
->conf_monitor_lst
;
236 if (ident_string
== NULL
|| strlen(ident_string
) == 0)
239 bzero(mon_hsync
, sizeof(parser_range
) * CONF_MAX_HSYNC
);
240 bzero(mon_vrefresh
, sizeof(parser_range
) * CONF_MAX_VREFRESH
);
242 XtSetArg(args
[0], XtNstring
, &str
);
243 XtGetValues(hsync
, args
, 1);
244 if ((mon_n_hsync
= string_to_parser_range(str
, mon_hsync
,
245 CONF_MAX_HSYNC
)) <= 0)
248 XtSetArg(args
[0], XtNstring
, &str
);
249 XtGetValues(vsync
, args
, 1);
250 if ((mon_n_vrefresh
= string_to_parser_range(str
, mon_vrefresh
,
251 CONF_MAX_VREFRESH
)) <= 0)
254 while (monitor
!= NULL
) {
255 if (monitor
!= current_monitor
&&
256 strcasecmp(ident_string
, monitor
->mon_identifier
) == 0)
258 monitor
= (XF86ConfMonitorPtr
)(monitor
->list
.next
);
265 string_to_parser_range(char *str
, parser_range
*range
, int nrange
)
270 if (str
== NULL
|| *str
== '\0' || range
== NULL
|| nrange
== 0)
274 while (*str
&& isspace(*str
))
276 if (!isdigit(*str
)) {
280 val
= strtod(str
, &str
);
281 while (*str
&& isspace(*str
))
283 if (*str
== ',' || *str
== '\0') {
286 range
[i
].lo
= range
[i
].hi
= val
;
287 if (++i
>= nrange
|| *str
== '\0')
291 else if (*str
!= '-')
295 while (*str
&& isspace(*str
))
297 if ((range
[i
].hi
= strtod(str
, &str
)) < range
[i
].lo
)
307 parser_range_to_string(char *str
, parser_range
*range
, int nrange
)
311 if (str
== NULL
|| range
== NULL
|| nrange
<= 0)
314 for (i
= len
= 0; i
< nrange
; i
++) {
316 len
+= XmuSnprintf(str
+ len
, PARSER_RANGE_SIZE
- len
, "%s",
318 if (range
[i
].lo
== range
[i
].hi
)
319 len
+= XmuSnprintf(str
+ len
, PARSER_RANGE_SIZE
- len
, "%g",
321 else if (range
[i
].lo
< range
[i
].hi
)
322 len
+= XmuSnprintf(str
+ len
, PARSER_RANGE_SIZE
- len
, "%g - %g",
323 range
[i
].lo
, range
[i
].hi
);
333 MonitorHsyncCallback(Widget w
, XtPointer user_data
, XtPointer call_data
)
335 XawListReturnStruct
*info
= (XawListReturnStruct
*)call_data
;
338 XtSetArg(args
[0], XtNstring
, hmodes_trans
[info
->list_index
]);
339 XtSetValues(hsync
, args
, 1);
344 MonitorVsyncCallback(Widget w
, XtPointer user_data
, XtPointer call_data
)
346 XawListReturnStruct
*info
= (XawListReturnStruct
*)call_data
;
349 XtSetArg(args
[0], XtNstring
, info
->string
);
350 XtSetValues(vsync
, args
, 1);
355 MonitorSelectCardCallback(Widget w
, XtPointer user_data
, XtPointer call_data
)
359 card
= (XF86ConfDevicePtr
)user_data
;
360 XtSetArg(args
[0], XtNlabel
, card
!= NULL
? card
->dev_identifier
: "");
361 XtSetValues(cmenu
, args
, 1);
365 MonitorLayout(XF86SetupInfo
*info
)
367 static int first
= 1, men
;
368 static Widget layout
, menu
;
369 XF86ConfDevicePtr device
= XF86Config
->conf_device_lst
;
379 layout
= XtCreateWidget("monitorl", formWidgetClass
,
381 XtCreateManagedWidget("hlabel", labelWidgetClass
, layout
, NULL
, 0);
382 hsync
= XtVaCreateManagedWidget("hsync", asciiTextWidgetClass
, layout
,
383 XtNeditType
, XawtextEdit
,
385 viewport
= XtCreateManagedWidget("hviewport", viewportWidgetClass
,
387 hlist
= XtVaCreateManagedWidget("hlist", listWidgetClass
, viewport
,
389 XtNnumberStrings
, sizeof(hmodes
) /
390 sizeof(hmodes
[0]), NULL
);
391 XtAddCallback(hlist
, XtNcallback
, MonitorHsyncCallback
, NULL
);
393 XtCreateManagedWidget("vlabel", labelWidgetClass
, layout
, NULL
, 0);
394 vsync
= XtVaCreateManagedWidget("vsync", asciiTextWidgetClass
, layout
,
395 XtNeditType
, XawtextEdit
,
397 viewport
= XtCreateManagedWidget("vviewport", viewportWidgetClass
,
399 vlist
= XtVaCreateManagedWidget("vlist", listWidgetClass
, viewport
,
401 XtNnumberStrings
, sizeof(vmodes
) /
402 sizeof(vmodes
[0]), NULL
);
403 XtAddCallback(vlist
, XtNcallback
, MonitorVsyncCallback
, NULL
);
405 XtCreateManagedWidget("clabel", labelWidgetClass
, layout
, NULL
, 0);
406 cmenu
= XtCreateManagedWidget("cmenu", menuButtonWidgetClass
,
409 XtRealizeWidget(layout
);
413 XtDestroyWidget(menu
);
416 * swaps names because XtDestroyWidget will only really destroy it
417 * when the code returns to XtAppMainLoop
419 menuname
= men
& 1 ? "mena" : "menb";
420 menu
= XtCreatePopupShell(menuname
, simpleMenuWidgetClass
,
422 XtSetArg(args
[0], XtNmenuName
, menuname
);
423 XtSetValues(cmenu
, args
, 1);
425 sme
= XtVaCreateManagedWidget("none", smeBSBObjectClass
, menu
,
427 XtAddCallback(sme
, XtNcallback
, MonitorSelectCardCallback
, NULL
);
429 while (device
!= NULL
) {
430 XF86ConfScreenPtr screen
= XF86Config
->conf_screen_lst
;
432 Bool sensitive
= True
;
434 while (screen
!= NULL
) {
435 if (screen
->scrn_device
== device
) {
436 sensitive
= screen
->scrn_monitor
== NULL
||
437 screen
->scrn_monitor
== current_monitor
;
440 screen
= (XF86ConfScreenPtr
)(screen
->list
.next
);
442 sme
= XtCreateManagedWidget(device
->dev_identifier
,
443 smeBSBObjectClass
, menu
,
446 XtAddCallback(sme
, XtNcallback
, MonitorSelectCardCallback
, device
);
447 XtSetSensitive(sme
, sensitive
);
449 device
= (XF86ConfDevicePtr
)(device
->list
.next
);
452 XtRealizeWidget(menu
);
454 XtChangeManagedSet(¤t
, 1, NULL
, NULL
, &layout
, 1);