First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / utils / xorgcfg / monitor-cfg.c
bloba443c54c2475cb34fc05d7379cf47f47a878f1c9
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>
31 #include "xf86config.h"
32 #include "monitor-cfg.h"
33 #include "screen.h"
34 #include <X11/extensions/xf86vmode.h>
35 #include <X11/Xaw/Form.h>
36 #include <X11/Xaw/Simple.h>
38 #include <ctype.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>
48 * Prototypes
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);
58 * Initialization
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[] = {
78 "31.5",
79 "31.5 - 35.1",
80 "31.5, 35.5",
81 "31.5, 35.15, 35.5",
82 "31.5 - 37.9",
83 "31.5 - 48.5",
84 "31.5 - 57.0",
85 "31.5 - 64.3",
86 "31.5 - 79.0",
87 "31.5 - 82.0",
88 "31.5 - 92.0",
89 "31.5 - 108.0",
90 "31.5 - 128.5",
91 "31.5 - 137.0"
94 static char *vmodes [] = { "50 - 70", "50 - 90", "50 - 100", "40 - 150", };
96 extern Widget config;
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;
106 * Implementation
108 XtPointer
109 MonitorConfig(XtPointer conf)
111 XF86ConfMonitorPtr monitor = (XF86ConfMonitorPtr)conf;
112 char monitor_name[48];
113 Arg args[1];
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])
122 (&xf86info);
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)
136 break;
138 screen = (XF86ConfScreenPtr)(screen->list.next);
140 if (screen != NULL) {
141 oldcard = card = screen->scrn_device;
142 XtSetArg(args[0], XtNlabel, card->dev_identifier);
144 else {
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);
153 *str = '\0';
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);
161 *str = '\0';
162 parser_range_to_string(str, mon_vrefresh, mon_n_vrefresh);
163 XtSetArg(args[0], XtNstring, str);
164 XtSetValues(vsync, args, 1);
166 else {
167 XF86ConfMonitorPtr monitor = XF86Config->conf_monitor_lst;
168 int nmonitors = 0;
170 oldcard = card = NULL;
171 while (monitor != NULL) {
172 ++nmonitors;
173 monitor = (XF86ConfMonitorPtr)(monitor->list.next);
175 do {
176 XmuSnprintf(monitor_name, sizeof(monitor_name),
177 "Monitor%d", nmonitors);
178 ++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) {
209 int i;
211 for (i = 0; i < computer.num_devices; i++)
212 if (computer.devices[i]->widget == config)
213 break;
214 if (computer.devices[i]->config == NULL)
215 XF86Config->conf_monitor_lst =
216 xf86addMonitor(XF86Config->conf_monitor_lst,
217 monitor);
218 computer.devices[i]->config = (XtPointer)monitor;
219 ChangeScreen(monitor, monitor, card, oldcard);
220 DrawCables();
223 return (monitor);
226 return (NULL);
229 static Bool
230 MonitorConfigCheck(void)
232 char *str;
233 Arg args[1];
234 XF86ConfMonitorPtr monitor = XF86Config->conf_monitor_lst;
236 if (ident_string == NULL || strlen(ident_string) == 0)
237 return (False);
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)
246 return (False);
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)
252 return (False);
254 while (monitor != NULL) {
255 if (monitor != current_monitor &&
256 strcasecmp(ident_string, monitor->mon_identifier) == 0)
257 return (False);
258 monitor = (XF86ConfMonitorPtr)(monitor->list.next);
261 return (True);
265 string_to_parser_range(char *str, parser_range *range, int nrange)
267 double val;
268 int i = 0;
270 if (str == NULL || *str == '\0' || range == NULL || nrange == 0)
271 return (0);
273 while (*str) {
274 while (*str && isspace(*str))
275 ++str;
276 if (!isdigit(*str)) {
277 ++str;
278 continue;
280 val = strtod(str, &str);
281 while (*str && isspace(*str))
282 ++str;
283 if (*str == ',' || *str == '\0') {
284 if (*str)
285 ++str;
286 range[i].lo = range[i].hi = val;
287 if (++i >= nrange || *str == '\0')
288 break;
289 continue;
291 else if (*str != '-')
292 return (0);
293 ++str;
294 range[i].lo = val;
295 while (*str && isspace(*str))
296 ++str;
297 if ((range[i].hi = strtod(str, &str)) < range[i].lo)
298 return (0);
299 if (++i >= nrange)
300 break;
303 return (i);
307 parser_range_to_string(char *str, parser_range *range, int nrange)
309 int i, len;
311 if (str == NULL || range == NULL || nrange <= 0)
312 return (0);
314 for (i = len = 0; i < nrange; i++) {
315 if (i > 0)
316 len += XmuSnprintf(str + len, PARSER_RANGE_SIZE - len, "%s",
317 ", ");
318 if (range[i].lo == range[i].hi)
319 len += XmuSnprintf(str + len, PARSER_RANGE_SIZE - len, "%g",
320 range[i].lo);
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);
324 else
325 return (0);
328 return (i);
331 /*ARGSUSED*/
332 static void
333 MonitorHsyncCallback(Widget w, XtPointer user_data, XtPointer call_data)
335 XawListReturnStruct *info = (XawListReturnStruct *)call_data;
336 Arg args[1];
338 XtSetArg(args[0], XtNstring, hmodes_trans[info->list_index]);
339 XtSetValues(hsync, args, 1);
342 /*ARGSUSED*/
343 static void
344 MonitorVsyncCallback(Widget w, XtPointer user_data, XtPointer call_data)
346 XawListReturnStruct *info = (XawListReturnStruct *)call_data;
347 Arg args[1];
349 XtSetArg(args[0], XtNstring, info->string);
350 XtSetValues(vsync, args, 1);
353 /*ARGSUSED*/
354 static void
355 MonitorSelectCardCallback(Widget w, XtPointer user_data, XtPointer call_data)
357 Arg args[1];
359 card = (XF86ConfDevicePtr)user_data;
360 XtSetArg(args[0], XtNlabel, card != NULL ? card->dev_identifier : "");
361 XtSetValues(cmenu, args, 1);
364 void
365 MonitorLayout(XF86SetupInfo *info)
367 static int first = 1, men;
368 static Widget layout, menu;
369 XF86ConfDevicePtr device = XF86Config->conf_device_lst;
370 Widget sme;
371 Arg args[1];
372 char *menuname;
374 if (first) {
375 Widget viewport;
377 first = 0;
379 layout = XtCreateWidget("monitorl", formWidgetClass,
380 configp, NULL, 0);
381 XtCreateManagedWidget("hlabel", labelWidgetClass, layout, NULL, 0);
382 hsync = XtVaCreateManagedWidget("hsync", asciiTextWidgetClass, layout,
383 XtNeditType, XawtextEdit,
384 NULL);
385 viewport = XtCreateManagedWidget("hviewport", viewportWidgetClass,
386 layout, NULL, 0);
387 hlist = XtVaCreateManagedWidget("hlist", listWidgetClass, viewport,
388 XtNlist, hmodes,
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,
396 NULL);
397 viewport = XtCreateManagedWidget("vviewport", viewportWidgetClass,
398 layout, NULL, 0);
399 vlist = XtVaCreateManagedWidget("vlist", listWidgetClass, viewport,
400 XtNlist, vmodes,
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,
407 layout, NULL, 0);
409 XtRealizeWidget(layout);
412 if (menu != NULL)
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,
421 cmenu, NULL, 0);
422 XtSetArg(args[0], XtNmenuName, menuname);
423 XtSetValues(cmenu, args, 1);
424 ++men;
425 sme = XtVaCreateManagedWidget("none", smeBSBObjectClass, menu,
426 NULL);
427 XtAddCallback(sme, XtNcallback, MonitorSelectCardCallback, NULL);
429 while (device != NULL) {
430 XF86ConfScreenPtr screen = XF86Config->conf_screen_lst;
431 Widget sme;
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;
438 break;
440 screen = (XF86ConfScreenPtr)(screen->list.next);
442 sme = XtCreateManagedWidget(device->dev_identifier,
443 smeBSBObjectClass, menu,
444 NULL, 0);
445 if (sensitive)
446 XtAddCallback(sme, XtNcallback, MonitorSelectCardCallback, device);
447 XtSetSensitive(sme, sensitive);
449 device = (XF86ConfDevicePtr)(device->list.next);
452 XtRealizeWidget(menu);
454 XtChangeManagedSet(&current, 1, NULL, NULL, &layout, 1);
455 current = layout;