1 /* $XFree86: xc/programs/xvidtune/xvidtune.c,v 3.35tsi Exp $ */
2
3 /*
4
5 Copyright (c) 1995 Kaleb S. KEITHLEY
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES
22 OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 OTHER DEALINGS IN THE SOFTWARE.
25
26 Except as contained in this notice, the name of Kaleb S. KEITHLEY
27 shall not be used in advertising or otherwise to promote the sale, use
28 or other dealings in this Software without prior written authorization
29 from Kaleb S. KEITHLEY.
30
31 */
32
33 #include <X11/Intrinsic.h>
34 #include <X11/Shell.h>
35 #include <X11/StringDefs.h>
36 #include <X11/Xatom.h>
37 #include <X11/Xaw/Form.h>
38 #include <X11/Xaw/Scrollbar.h>
39 #include <X11/Xaw/Label.h>
40 #include <X11/Xaw/Command.h>
41 #include <X11/Xaw/AsciiText.h>
42 #include <X11/Xaw/Box.h>
43 #include <X11/Xaw/Toggle.h>
44 #include <X11/Xmu/StdSel.h>
45 #include <X11/Xmd.h>
46 #include <X11/extensions/xf86vmode.h>
47 #include <ctype.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <signal.h>
51
52 static int MajorVersion, MinorVersion;
53 static int EventBase, ErrorBase;
54 static int dot_clock, mode_flags;
55 static unsigned long TestTimeout=5000; /* Default test timeout */
56 static XtSignalId sigId;
57
58 /* Minimum extension version required */
59 #define MINMAJOR 0
60 #define MINMINOR 5
61
62 /* Mode flags -- ignore flags not in V_FLAG_MASK */
63 #define V_FLAG_MASK 0x1FF;
64 #define V_PHSYNC 0x001
65 #define V_NHSYNC 0x002
66 #define V_PVSYNC 0x004
67 #define V_NVSYNC 0x008
68 #define V_INTERLACE 0x010
69 #define V_DBLSCAN 0x020
70 #define V_CSYNC 0x040
71 #define V_PCSYNC 0x080
72 #define V_NCSYNC 0x100
73
74 typedef enum { HDisplay, HSyncStart, HSyncEnd, HTotal,
75 VDisplay, VSyncStart, VSyncEnd, VTotal, Flags,
76 InvertVclk, BlankDelay1, BlankDelay2, EarlySc,
77 PixelClock, HSyncRate, VSyncRate, fields_num } fields;
78
79 typedef struct {
80 fields me;
81 fields use;
82 int val;
83 int lastpercent;
84 int range;
85 Widget textwidget;
86 Widget scrollwidget;
87 } ScrollData;
88
89 static struct _AppResources {
90 ScrollData field[fields_num];
91 Bool ad_installed;
92 int orig[fields_num];
93 int old[fields_num];
94 } AppRes = {
95 {
96 { HDisplay, },
97 { HSyncStart, HDisplay, },
98 { HSyncEnd, HDisplay, },
99 { HTotal, HDisplay, },
100 { VDisplay, },
101 { VSyncStart, VDisplay, },
102 { VSyncEnd, VDisplay, },
103 { VTotal, VDisplay, },
104 { Flags, },
105 { InvertVclk, },
106 { BlankDelay1, },
107 { BlankDelay2, },
108 { EarlySc, },
109 { PixelClock, },
110 { HSyncRate, },
111 { VSyncRate, },
112 },
113 };
114
115 static XtResource Resources[] = {
116 { "adInstalled", "AdInstalled", XtRBool, sizeof(Bool),
117 XtOffsetOf(struct _AppResources, ad_installed),
118 XtRImmediate, (XtPointer)FALSE },
119 { "hSyncStartRange", "SyncStartRange", XtRInt, sizeof(int),
120 XtOffsetOf(struct _AppResources, field[HSyncStart].range),
121 XtRImmediate, (XtPointer)200 },
122 { "hSyncEndRange", "SyncEndRange", XtRInt, sizeof(int),
123 XtOffsetOf(struct _AppResources, field[HSyncEnd].range),
124 XtRImmediate, (XtPointer)400 },
125 { "hTotalRange", "TotalRange", XtRInt, sizeof(int),
126 XtOffsetOf(struct _AppResources, field[HTotal].range),
127 XtRImmediate, (XtPointer)400 },
128 { "vSyncStartRange", "SyncStartRange", XtRInt, sizeof(int),
129 XtOffsetOf(struct _AppResources, field[VSyncStart].range),
130 XtRImmediate, (XtPointer)20 },
131 { "vSyncEndRange", "SyncEndRange", XtRInt, sizeof(int),
132 XtOffsetOf(struct _AppResources, field[VSyncEnd].range),
133 XtRImmediate, (XtPointer)40 },
134 { "vTotalRange", "TotalRange", XtRInt, sizeof(int),
135 XtOffsetOf(struct _AppResources, field[VTotal].range),
136 XtRImmediate, (XtPointer)80 },
137 };
138
139 static XtTranslations trans;
140
141 static Atom wm_delete_window;
142 static Widget invalid_mode_popup;
143 static Widget testing_popup;
144 static Widget Top;
145 static Widget auto_apply_toggle;
146
147 static Bool S3Specials = False;
148 static char modebuf[160];
149
150 static void UpdateSyncRates(Bool dolabels);
151
152 static void
CleanUp(Display * dpy)153 CleanUp(Display *dpy)
154 {
155 /* Make sure mode switching is not locked out at exit */
156 XF86VidModeLockModeSwitch(dpy, DefaultScreen(dpy), FALSE);
157 XFlush(dpy);
158 }
159
160 static void
CatchSig(int signal)161 CatchSig(int signal)
162 {
163 XtNoticeSignal(sigId);
164 }
165
166 static void
CatchXtSig(XtPointer closure,XtSignalId * id)167 CatchXtSig(XtPointer closure, XtSignalId *id)
168 {
169 CleanUp(XtDisplay(Top));
170 exit(3);
171 }
172
173 static Bool
GetModeLine(Display * dpy,int scrn)174 GetModeLine (Display* dpy, int scrn)
175 {
176 XF86VidModeModeLine mode_line;
177 fields i;
178
179 if (!XF86VidModeGetModeLine (dpy, scrn, &dot_clock, &mode_line))
180 return FALSE;
181
182 AppRes.field[HDisplay].val = mode_line.hdisplay;
183 AppRes.field[HSyncStart].val = mode_line.hsyncstart;
184 AppRes.field[HSyncEnd].val = mode_line.hsyncend;
185 AppRes.field[HTotal].val = mode_line.htotal;
186 AppRes.field[VDisplay].val = mode_line.vdisplay;
187 AppRes.field[VSyncStart].val = mode_line.vsyncstart;
188 AppRes.field[VSyncEnd].val = mode_line.vsyncend;
189 AppRes.field[VTotal].val = mode_line.vtotal;
190 mode_flags = mode_line.flags;
191 AppRes.field[Flags].val = mode_flags & V_FLAG_MASK;
192 AppRes.field[PixelClock].val = dot_clock;
193 UpdateSyncRates(FALSE);
194 if (mode_line.privsize && mode_line.private) {
195 S3Specials = True;
196 AppRes.field[InvertVclk].val = mode_line.private[1];
197 AppRes.field[BlankDelay1].val = mode_line.private[2] & 7;
198 AppRes.field[BlankDelay2].val = (mode_line.private[2] >> 4) & 7;
199 AppRes.field[EarlySc].val = mode_line.private[3];
200 }
201
202 for (i = HDisplay; i < fields_num; i++)
203 AppRes.orig[i] = AppRes.field[i].val;
204 return TRUE;
205 }
206
207 static Bool
GetMonitor(Display * dpy,int scrn)208 GetMonitor (Display* dpy, int scrn)
209 {
210 XF86VidModeMonitor monitor;
211 int i;
212
213 if (!XF86VidModeGetMonitor (dpy, scrn, &monitor))
214 return FALSE;
215
216 printf("Vendor: %s, Model: %s\n", monitor.vendor, monitor.model);
217 printf("Num hsync: %d, Num vsync: %d\n", monitor.nhsync, monitor.nvsync);
218 for (i = 0; i < monitor.nhsync; i++) {
219 printf("hsync range %d: %6.2f - %6.2f\n", i, monitor.hsync[i].lo,
220 monitor.hsync[i].hi);
221 }
222 for (i = 0; i < monitor.nvsync; i++) {
223 printf("vsync range %d: %6.2f - %6.2f\n", i, monitor.vsync[i].lo,
224 monitor.vsync[i].hi);
225 }
226 return TRUE;
227 }
228
229 static Bool
ModeSettable(void)230 ModeSettable(void)
231 {
232 if (AppRes.field[HTotal].val == 0 || AppRes.field[VTotal].val == 0)
233 return FALSE;
234 return TRUE;
235 }
236
237 static int hitError = 0;
238 static int (*xtErrorfunc)(Display *, XErrorEvent *);
239
240 static int
vidmodeError(Display * dis,XErrorEvent * err)241 vidmodeError(Display *dis, XErrorEvent *err)
242 {
243 if ((err->error_code >= ErrorBase &&
244 err->error_code < ErrorBase + XF86VidModeNumberErrors) ||
245 err->error_code == BadValue) {
246 hitError=1;
247 } else {
248 CleanUp(dis);
249 if (xtErrorfunc)
250 (*xtErrorfunc)(dis, err);
251 }
252 return 0; /* ignored */
253 }
254
255 static void
SetScrollbars(void)256 SetScrollbars (void)
257 {
258 fields i;
259
260 for (i = HDisplay; i <= Flags; i++) {
261
262 ScrollData* sdp = &AppRes.field[i];
263
264 if (sdp->scrollwidget != (Widget) NULL) {
265 int base;
266 float percent;
267
268 base = AppRes.field[sdp->use].val;
269 percent = ((float)(sdp->val - base)) / ((float)sdp->range);
270 XawScrollbarSetThumb (sdp->scrollwidget, percent, 0.0);
271 }
272 }
273 }
274
275 static void
QuitCB(Widget w,XtPointer client,XtPointer call)276 QuitCB (Widget w, XtPointer client, XtPointer call)
277 {
278 CleanUp(XtDisplay(w));
279 #if XtSpecificationRelease < 6
280 exit (0);
281 #else
282 XtAppSetExitFlag (XtWidgetToApplicationContext (w));
283 #endif
284 }
285
286 static void
popdownInvalid(Widget w,XtPointer client,XtPointer call)287 popdownInvalid(Widget w, XtPointer client, XtPointer call)
288 {
289 XtPopdown((Widget)client);
290 }
291
292 static void
ApplyCB(Widget w,XtPointer client,XtPointer call)293 ApplyCB (Widget w, XtPointer client, XtPointer call)
294 {
295 XF86VidModeModeLine mode_line;
296 INT32 S3private[4];
297 unsigned int i;
298 char* string;
299 Boolean state;
300
301 mode_line.hdisplay = AppRes.field[HDisplay].val;
302 mode_line.hsyncstart = AppRes.field[HSyncStart].val;
303 mode_line.hsyncend = AppRes.field[HSyncEnd].val;
304 mode_line.htotal = AppRes.field[HTotal].val;
305 mode_line.vdisplay = AppRes.field[VDisplay].val;
306 mode_line.vsyncstart = AppRes.field[VSyncStart].val;
307 mode_line.vsyncend = AppRes.field[VSyncEnd].val;
308 mode_line.vtotal = AppRes.field[VTotal].val;
309 /* Don't read flags from widget */
310 #if 0
311 XtVaGetValues (AppRes.field[Flags].textwidget,
312 XtNstring, &string, NULL);
313 (void) sscanf (string, "%x", &i);
314 #endif
315 mode_line.flags = mode_flags;
316 if (S3Specials) {
317 mode_line.privsize = 4;
318 mode_line.private = S3private;
319 mode_line.private[0] = (1 << 1) | (1 << 2) | (1 << 3);
320 XtVaGetValues(AppRes.field[InvertVclk].textwidget,
321 XtNstate, &state, NULL);
322 AppRes.field[InvertVclk].val = state ? 1 : 0;
323 mode_line.private[1] = AppRes.field[InvertVclk].val;
324 XtVaGetValues (AppRes.field[BlankDelay1].textwidget,
325 XtNstring, &string, NULL);
326 (void) sscanf (string, "%x", &i);
327 AppRes.field[BlankDelay1].val = i;
328 mode_line.private[2] = AppRes.field[BlankDelay1].val;
329 XtVaGetValues (AppRes.field[BlankDelay2].textwidget,
330 XtNstring, &string, NULL);
331 (void) sscanf (string, "%x", &i);
332 AppRes.field[BlankDelay2].val = i;
333 mode_line.private[2] |= AppRes.field[BlankDelay2].val << 4;
334 XtVaGetValues(AppRes.field[EarlySc].textwidget,
335 XtNstate, &state, NULL);
336 AppRes.field[EarlySc].val = state ? 1 : 0;
337 mode_line.private[3] = AppRes.field[EarlySc].val;
338 } else
339 mode_line.privsize = 0;
340
341 hitError = 0;
342
343 XF86VidModeModModeLine (XtDisplay (w), DefaultScreen (XtDisplay (w)),
344 &mode_line);
345 XSync(XtDisplay (w), False); /* process errors */
346 if (hitError) {
347 XBell(XtDisplay (w), 80);
348 XtPopup(invalid_mode_popup, XtGrabExclusive /*XtGrabNone*/);
349 }
350 }
351
352
353 static void
SetLabel(fields i)354 SetLabel(fields i)
355 {
356 ScrollData* sdp = &AppRes.field[i];
357
358 if (sdp->textwidget != (Widget) NULL) {
359 char buf[10];
360 Boolean state;
361
362 /*
363 * Disable AutoApply so that the apply doesn't happen more than
364 * once as a consequence of callbacks being called because of the
365 * XtSetValues calls
366 */
367
368 XtVaGetValues(auto_apply_toggle, XtNstate, &state, NULL);
369 if (state)
370 XtVaSetValues(auto_apply_toggle, XtNstate, 0, NULL);
371
372 if (i == Flags)
373 (void) snprintf (buf, sizeof(buf), "%04x", sdp->val);
374 else if (i >= PixelClock && i <= VSyncRate)
375 (void) snprintf (buf, sizeof(buf), "%6.2f", (float)sdp->val / 1000.0);
376 else if (i == BlankDelay1 || i == BlankDelay2) {
377 (void) snprintf (buf, sizeof(buf), "%d", sdp->val);
378 } else
379 (void) snprintf (buf, sizeof(buf), "%5d", sdp->val);
380
381 sdp->lastpercent = -1;
382 if (i == Flags) {
383 XawTextBlock text;
384
385 text.firstPos = 0;
386 text.length = 4;
387 text.ptr = buf;
388 text.format = XawFmt8Bit;
389 XawTextReplace (sdp->textwidget, 0, 4, &text);
390 } else if (i == BlankDelay1 || i == BlankDelay2) {
391 XawTextBlock text;
392
393 text.firstPos = 0;
394 text.length = 1;
395 text.ptr = buf;
396 XawTextReplace (sdp->textwidget, 0, 1, &text);
397 } else if (i == InvertVclk || i == EarlySc) {
398 XtVaSetValues (sdp->textwidget, XtNstate, sdp->val, NULL);
399 } else
400 XtVaSetValues (sdp->textwidget, XtNlabel, buf, NULL);
401
402 if (state)
403 XtVaSetValues(auto_apply_toggle, XtNstate, 1, NULL);
404 }
405
406 }
407
408 static void
UpdateSyncRates(Bool dolabels)409 UpdateSyncRates(Bool dolabels)
410 {
411 if (!ModeSettable())
412 return;
413
414 AppRes.field[HSyncRate].val = AppRes.field[PixelClock].val * 1000 /
415 AppRes.field[HTotal].val;
416 AppRes.field[VSyncRate].val = AppRes.field[HSyncRate].val * 1000 /
417 AppRes.field[VTotal].val;
418 if (mode_flags & V_INTERLACE)
419 AppRes.field[VSyncRate].val *= 2;
420 else if (mode_flags & V_DBLSCAN)
421 AppRes.field[VSyncRate].val /= 2;
422 if (dolabels) {
423 SetLabel(HSyncRate);
424 SetLabel(VSyncRate);
425 }
426 }
427
428 static void
RestoreCB(Widget w,XtPointer client,XtPointer call)429 RestoreCB (Widget w, XtPointer client, XtPointer call)
430 {
431 fields i;
432 Boolean state;
433
434 for (i = HDisplay; i < fields_num; i++) {
435 AppRes.field[i].val = AppRes.orig[i];
436 SetLabel(i);
437 }
438 SetScrollbars ();
439 XtVaGetValues(auto_apply_toggle, XtNstate, &state, NULL);
440 if (state)
441 ApplyCB (w, client, call);
442 }
443
444
445 static void
ApplyIfAutoCB(Widget w,XtPointer client,XtPointer call)446 ApplyIfAutoCB (Widget w, XtPointer client, XtPointer call)
447 {
448 Boolean state;
449
450 XtVaGetValues(auto_apply_toggle, XtNstate, &state, NULL);
451 if (state)
452 ApplyCB (w, client, call);
453 }
454
455
456 static void
FetchCB(Widget w,XtPointer client,XtPointer call)457 FetchCB (Widget w, XtPointer client, XtPointer call)
458 {
459 fields i;
460 (void) GetModeLine(XtDisplay (w), DefaultScreen (XtDisplay (w)));
461 SetScrollbars ();
462 for (i = HDisplay; i < fields_num; i++) {
463 SetLabel(i);
464 }
465 }
466
467 static XtIntervalId TOid;
468
469 static void
TestTO(XtPointer client,XtIntervalId * id)470 TestTO (XtPointer client, XtIntervalId* id)
471 {
472 fields i;
473 for (i = HDisplay; i < fields_num; i++)
474 AppRes.field[i].val = AppRes.orig[i];
475
476 ApplyCB ((Widget) client, NULL, NULL);
477
478 for (i = HDisplay; i < fields_num; i++)
479 AppRes.field[i].val = AppRes.old[i];
480 SetScrollbars ();
481
482 XtPopdown(testing_popup);
483 }
484
485 static void
TestTOCB(Widget w,XtPointer client,XtPointer call)486 TestTOCB (Widget w, XtPointer client, XtPointer call)
487 {
488 XtRemoveTimeOut(TOid);
489 TestTO(w, (XtIntervalId *) NULL);
490 }
491
492 static void
TestCB(Widget w,XtPointer client,XtPointer call)493 TestCB (Widget w, XtPointer client, XtPointer call)
494 {
495 fields i;
496 for (i = HDisplay; i < fields_num; i++)
497 AppRes.old[i] = AppRes.field[i].val;
498
499 XtPopup(testing_popup, XtGrabExclusive /*XtGrabNone*/);
500 XSync(XtDisplay(w), False);
501 TOid = XtAppAddTimeOut (XtWidgetToApplicationContext (w),
502 TestTimeout, TestTO, (XtPointer) w);
503
504 ApplyCB (w, client, call);
505 }
506
507 static Boolean
ConvertSelection(Widget w,Atom * selection,Atom * target,Atom * type,XtPointer * value,unsigned long * length,int * format)508 ConvertSelection(
509 Widget w,
510 Atom *selection, Atom *target, Atom *type,
511 XtPointer *value,
512 unsigned long *length,
513 int *format)
514 {
515 if (XmuConvertStandardSelection(w, CurrentTime, selection, target, type,
516 (XPointer *) value, length, format))
517 return True;
518
519 if (*target == XA_STRING) {
520 *type = XA_STRING;
521 *value = modebuf;
522 *length = strlen(*value);
523 *format = 8;
524 return True;
525 }
526 return False;
527 }
528
529 static void
ShowCB(Widget w,XtPointer client,XtPointer call)530 ShowCB(Widget w, XtPointer client, XtPointer call)
531 {
532 Time time;
533 char tmpbuf[16];
534
535 snprintf(tmpbuf, sizeof(tmpbuf), "\"%dx%d\"",
536 AppRes.field[HDisplay].val, AppRes.field[VDisplay].val);
537 snprintf(modebuf, sizeof(modebuf),
538 "%-11s %6.2f %4d %4d %4d %4d %4d %4d %4d %4d",
539 tmpbuf, (float)dot_clock/1000.0,
540 AppRes.field[HDisplay].val,
541 AppRes.field[HSyncStart].val,
542 AppRes.field[HSyncEnd].val,
543 AppRes.field[HTotal].val,
544 AppRes.field[VDisplay].val,
545 AppRes.field[VSyncStart].val,
546 AppRes.field[VSyncEnd].val,
547 AppRes.field[VTotal].val);
548 /* Print out the flags (if any) */
549 if (mode_flags & V_PHSYNC) strcat(modebuf, " +hsync");
550 if (mode_flags & V_NHSYNC) strcat(modebuf, " -hsync");
551 if (mode_flags & V_PVSYNC) strcat(modebuf, " +vsync");
552 if (mode_flags & V_NVSYNC) strcat(modebuf, " -vsync");
553 if (mode_flags & V_INTERLACE) strcat(modebuf, " interlace");
554 if (mode_flags & V_CSYNC) strcat(modebuf, " composite");
555 if (mode_flags & V_PCSYNC) strcat(modebuf, " +csync");
556 if (mode_flags & V_NCSYNC) strcat(modebuf, " -csync");
557 if (mode_flags & V_DBLSCAN) strcat(modebuf, " doublescan");
558 printf("%s\n", modebuf);
559 time = XtLastTimestampProcessed(XtDisplay(w));
560 XtOwnSelection(w, XA_PRIMARY, time, ConvertSelection, NULL, NULL);
561 if (S3Specials) {
562 unsigned int i;
563 Boolean state;
564 char *string;
565
566 XtVaGetValues(AppRes.field[InvertVclk].textwidget,
567 XtNstate, &state, NULL);
568 AppRes.field[InvertVclk].val = state ? 1 : 0;
569 XtVaGetValues (AppRes.field[BlankDelay1].textwidget,
570 XtNstring, &string, NULL);
571 (void) sscanf (string, "%x", &i);
572 AppRes.field[BlankDelay1].val = i;
573 XtVaGetValues (AppRes.field[BlankDelay2].textwidget,
574 XtNstring, &string, NULL);
575 (void) sscanf (string, "%x", &i);
576 AppRes.field[BlankDelay2].val = i;
577 XtVaGetValues(AppRes.field[EarlySc].textwidget,
578 XtNstate, &state, NULL);
579 AppRes.field[EarlySc].val = state ? 1 : 0;
580 if (AppRes.field[InvertVclk].val != AppRes.orig[InvertVclk])
581 printf("InvertVCLK\t\"%dx%d\" %d\n", AppRes.field[HDisplay].val,
582 AppRes.field[VDisplay].val, AppRes.field[InvertVclk].val);
583 if (AppRes.field[EarlySc].val != AppRes.orig[EarlySc])
584 printf("EarlySC\t\t\"%dx%d\" %d\n", AppRes.field[HDisplay].val,
585 AppRes.field[VDisplay].val, AppRes.field[EarlySc].val);
586 if (AppRes.field[BlankDelay1].val != AppRes.orig[BlankDelay1]
587 || AppRes.field[BlankDelay2].val != AppRes.orig[BlankDelay2])
588 printf("BlankDelay\t\"%dx%d\" %d %d\n", AppRes.field[HDisplay].val,
589 AppRes.field[VDisplay].val, AppRes.field[BlankDelay1].val,
590 AppRes.field[BlankDelay2].val);
591 }
592 printf("\n");
593 }
594
595 static void
AdjustCB(Widget w,XtPointer client,XtPointer call)596 AdjustCB(Widget w, XtPointer client, XtPointer call)
597 {
598 int what = (long) client;
599 Boolean state;
600
601 switch (what) {
602 case HSyncStart:
603 if (AppRes.field[HSyncEnd].val + 4 < AppRes.field[HTotal].val) {
604 AppRes.field[HSyncEnd].val += 4;
605 AppRes.field[HSyncStart].val += 4;
606 SetLabel(HSyncStart);
607 SetLabel(HSyncEnd);
608 } else
609 XBell(XtDisplay(w), 80);
610 break;
611 case -HSyncStart:
612 if (AppRes.field[HSyncStart].val - 4 > AppRes.field[HDisplay].val) {
613 AppRes.field[HSyncEnd].val -= 4;
614 AppRes.field[HSyncStart].val -= 4;
615 SetLabel(HSyncStart);
616 SetLabel(HSyncEnd);
617 } else
618 XBell(XtDisplay(w), 80);
619 break;
620 case HTotal:
621 AppRes.field[HTotal].val += 4;
622 SetLabel(HTotal);
623 UpdateSyncRates(TRUE);
624 break;
625 case -HTotal:
626 if (AppRes.field[HTotal].val - 4 > AppRes.field[HSyncEnd].val) {
627 AppRes.field[HTotal].val -= 4;
628 SetLabel(HTotal);
629 UpdateSyncRates(TRUE);
630 } else
631 XBell(XtDisplay(w), 80);
632 break;
633 case VSyncStart:
634 if (AppRes.field[VSyncEnd].val + 4 < AppRes.field[VTotal].val) {
635 AppRes.field[VSyncEnd].val += 4;
636 AppRes.field[VSyncStart].val += 4;
637 SetLabel(VSyncStart);
638 SetLabel(VSyncEnd);
639 } else
640 XBell(XtDisplay(w), 80);
641 break;
642 case -VSyncStart:
643 if (AppRes.field[VSyncStart].val - 4 > AppRes.field[VDisplay].val) {
644 AppRes.field[VSyncEnd].val -= 4;
645 AppRes.field[VSyncStart].val -= 4;
646 SetLabel(VSyncStart);
647 SetLabel(VSyncEnd);
648 } else
649 XBell(XtDisplay(w), 80);
650 break;
651 case VTotal:
652 AppRes.field[VTotal].val += 4;
653 SetLabel(VTotal);
654 UpdateSyncRates(TRUE);
655 break;
656 case -VTotal:
657 if (AppRes.field[VTotal].val - 4 > AppRes.field[VSyncEnd].val) {
658 AppRes.field[VTotal].val -= 4;
659 SetLabel(VTotal);
660 UpdateSyncRates(TRUE);
661 } else
662 XBell(XtDisplay(w), 80);
663 break;
664 }
665 SetScrollbars ();
666 XtVaGetValues(auto_apply_toggle, XtNstate, &state, NULL);
667 if (state)
668 ApplyCB (w, client, call);
669 }
670
671
672 #if 0
673 static void
674 EditCB (Widget w, XtPointer client, XtPointer call)
675 {
676 int base, current, i, len;
677 int lower, upper;
678 float percent;
679 ScrollData* sdp = (ScrollData*) client;
680
681 len = strlen (sdp->string);
682
683 for (i = 0; i < len; i++) {
684 if (!(isdigit (sdp->string[i]) || isspace (sdp->string[i]))) {
685 XBell (XtDisplay(XtParent(w)), 100);
686 return;
687 }
688 }
689 switch (sdp->me) {
690 case HSyncStart:
691 lower = atoi (AppRes.field[HDisplay].string);
692 upper = atoi (AppRes.field[HSyncEnd].string);
693 break;
694
695 case HSyncEnd:
696 lower = atoi (AppRes.field[HSyncStart].string);
697 upper = atoi (AppRes.field[HTotal].string);
698 break;
699
700 case HTotal:
701 lower = atoi (AppRes.field[HSyncEnd].string);
702 upper = atoi (AppRes.field[HDisplay].string) +
703 AppRes.field[HTotal].range;
704 break;
705
706 case VSyncStart:
707 lower = atoi (AppRes.field[VDisplay].string);
708 upper = atoi (AppRes.field[VSyncEnd].string);
709 break;
710
711 case VSyncEnd:
712 lower = atoi (AppRes.field[VSyncStart].string);
713 upper = atoi (AppRes.field[VTotal].string);
714 break;
715
716 case VTotal:
717 lower = atoi (AppRes.field[VSyncEnd].string);
718 upper = atoi (AppRes.field[VDisplay].string) +
719 AppRes.field[VTotal].range;
720 break;
721 }
722 current = atoi (sdp->string);
723 if (current < lower || current > upper) {
724 XawTextBlock text;
725 char tmp[6];
726
727 if (current < lower) {
728 (void) snprintf (tmp, sizeof(tmp), "%5d", lower);
729 current = lower;
730 } else {
731 (void) snprintf (tmp, sizeof(tmp), "%5d", upper);
732 current = upper;
733 }
734 text.firstPos = 0;
735 text.length = strlen (tmp);
736 text.ptr = tmp;
737 text.format = XawFmt8Bit;
738 XawTextReplace (sdp->textwidget, 0, text.length, &text);
739 }
740 base = atoi (AppRes.field[sdp->use].string);
741 percent = ((float)(current - base)) / ((float)sdp->range);
742 XawScrollbarSetThumb (sdp->scrollwidget, percent, 0.0);
743 }
744 #endif
745
746 static void
FlagsEditCB(Widget w,XtPointer client,XtPointer call)747 FlagsEditCB (Widget w, XtPointer client, XtPointer call)
748 {
749 int i, len;
750 char* string;
751 fields findex = (fields) (unsigned long) client;
752 ScrollData* sdp = &AppRes.field[findex];
753
754 XtVaGetValues (w, XtNstring, &string, NULL);
755 len = strlen (string);
756 if (len > 4) {
757 char buf[5];
758
759 XBell (XtDisplay(XtParent(w)), 100);
760 (void) strncpy (buf, string, 4);
761 buf[4] = '\0';
762 XtVaSetValues (sdp->textwidget, XtNstring, buf, NULL);
763 XawTextSetInsertionPoint (sdp->textwidget, 4);
764 }
765
766 for (i = 0; i < len; i++) {
767 if (!isxdigit (string[i])) {
768 XBell (XtDisplay(XtParent(w)), 100);
769 }
770 }
771 }
772
773 static void
BlankEditCB(Widget w,XtPointer client,XtPointer call)774 BlankEditCB (Widget w, XtPointer client, XtPointer call)
775 {
776 int len;
777 char* string;
778 fields findex = (fields) (unsigned long) client;
779 ScrollData* sdp = &AppRes.field[findex];
780 char buf[2], old;
781 Boolean state;
782 Boolean noAuto = False;
783
784 XtVaGetValues (w, XtNstring, &string, NULL);
785 len = strlen (string);
786 if (len == 0) {
787 XBell (XtDisplay(XtParent(w)), 100);
788 strcpy(buf, "0");
789 XtVaSetValues (sdp->textwidget, XtNstring, buf, NULL);
790 XawTextSetInsertionPoint (sdp->textwidget, 1);
791 return;
792 }
793 if (len > 1) {
794 if (XawTextGetInsertionPoint(sdp->textwidget) < 1) {
795 buf[0] = string[0];
796 old = string[1];
797 } else {
798 buf[0] = string[1];
799 old = string[0];
800 }
801 if (buf[0] == '+' && old < '7')
802 buf[0] = old + 1;
803 else if (buf[0] == '-' && old > '0')
804 buf[0] = old - 1;
805 if (!isdigit(buf[0]) || buf[0] > '7') {
806 XBell (XtDisplay(XtParent(w)), 100);
807 buf[0] = old;
808 if (!isdigit(buf[0]) || buf[0] > '7')
809 buf[0] = '0';
810 noAuto = True;
811 }
812 buf[1] = '\0';
813 XtVaSetValues (sdp->textwidget, XtNstring, buf, NULL);
814 XawTextSetInsertionPoint (sdp->textwidget, 1);
815 }
816 XtVaGetValues(auto_apply_toggle, XtNstate, &state, NULL);
817 if (state && !noAuto)
818 ApplyCB (sdp->textwidget, client, call);
819 }
820
821 static void
ChangeBlankCB(Widget w,XtPointer client,XtPointer call)822 ChangeBlankCB (Widget w, XtPointer client, XtPointer call)
823 {
824 char* string;
825 char buf[2];
826 fields findex;
827 ScrollData* sdp;
828 Boolean state;
829 int what = (long) client;
830
831
832 if (what < 0)
833 findex = (fields)-what;
834 else
835 findex = (fields)what;
836 sdp = &AppRes.field[findex];
837
838 XtVaGetValues (sdp->textwidget, XtNstring, &string, NULL);
839 if (what > 0)
840 string[0]++;
841 else
842 string[0]--;
843
844 if (string[0] < '0' || string[0] > '7') {
845 XBell (XtDisplay(XtParent(w)), 100);
846 return;
847 }
848
849 buf[0] = string[0];
850 buf[1] = '\0';
851 XtVaSetValues (sdp->textwidget, XtNstring, buf, NULL);
852 XawTextSetInsertionPoint (sdp->textwidget, 1);
853
854 XtVaGetValues(auto_apply_toggle, XtNstate, &state, NULL);
855 if (state)
856 ApplyCB (sdp->textwidget, client, call);
857 }
858
859 static int
isValid(int val,int field)860 isValid(int val, int field)
861 {
862 switch(field) {
863 case HSyncStart:
864 if (val+8 > AppRes.field[HSyncEnd].val)
865 val = AppRes.field[HSyncEnd].val - 8;
866 break;
867 case HSyncEnd:
868 if (val-8 < AppRes.field[HSyncStart].val)
869 val = AppRes.field[HSyncStart].val + 8;
870 if (val > AppRes.field[HTotal].val)
871 val = AppRes.field[HTotal].val;
872 break;
873 case HTotal:
874 if (val < AppRes.field[HSyncEnd].val)
875 val = AppRes.field[HSyncEnd].val;
876 break;
877 case VSyncStart:
878 if (val+8 > AppRes.field[VSyncEnd].val)
879 val = AppRes.field[VSyncEnd].val - 8;
880 break;
881 case VSyncEnd:
882 if (val-8 < AppRes.field[VSyncStart].val)
883 val = AppRes.field[VSyncStart].val + 8;
884 if (val > AppRes.field[VTotal].val)
885 val = AppRes.field[VTotal].val;
886 break;
887 case VTotal:
888 if (val < AppRes.field[VSyncEnd].val)
889 val = AppRes.field[VSyncEnd].val;
890 break;
891 }
892 return val;
893 }
894
895 static void
ScrollCB(Widget w,XtPointer client,XtPointer call)896 ScrollCB (Widget w, XtPointer client, XtPointer call)
897 {
898 float percent = *(float*) call;
899 int ipercent = percent * 100;
900 int fieldindex = (long) client;
901 ScrollData* sdp = &AppRes.field[fieldindex];
902
903
904
905 if (ipercent != sdp->lastpercent) {
906 int tmp_val;
907 char buf[6];
908
909 tmp_val = AppRes.field[sdp->use].val;
910 tmp_val += (int) (((float)sdp->range) * percent);
911
912 sdp->val = isValid(tmp_val, fieldindex);
913
914 sdp->lastpercent = ipercent;
915 (void) snprintf (buf, sizeof(buf), "%5d", sdp->val);
916 XtVaSetValues (sdp->textwidget, XtNlabel, buf, NULL);
917 if (sdp->val != tmp_val) {
918 int base;
919 float percent;
920
921 base = AppRes.field[sdp->use].val;
922 percent = ((float)(sdp->val - base)) / ((float)sdp->range);
923 /* This doesn't always work, why? */
924 XawScrollbarSetThumb (sdp->scrollwidget, percent, 0.0);
925 }
926 if (fieldindex == HTotal || fieldindex == VTotal)
927 UpdateSyncRates(TRUE);
928 }
929 }
930
931 static void
SwitchCB(Widget w,XtPointer client,XtPointer call)932 SwitchCB (Widget w, XtPointer client, XtPointer call)
933 {
934 XF86VidModeLockModeSwitch(XtDisplay(w), DefaultScreen (XtDisplay (w)),
935 FALSE);
936 XF86VidModeSwitchMode(XtDisplay(w), DefaultScreen (XtDisplay (w)),
937 (int)(long) client);
938 XF86VidModeLockModeSwitch(XtDisplay(w), DefaultScreen (XtDisplay (w)),
939 TRUE);
940 FetchCB(w, NULL, NULL);
941 }
942
943 static void
AddCallback(Widget w,String callback_name,XtCallbackProc callback,XtPointer client_data)944 AddCallback (
945 Widget w,
946 String callback_name,
947 XtCallbackProc callback,
948 XtPointer client_data)
949 {
950 Widget src;
951
952 XtVaGetValues (w, XtNtextSource, &src, NULL);
953 XtAddCallback (src, callback_name, callback, client_data);
954 }
955
956 static void
CreateTyp(Widget form,fields findex,String w1name,String w2name,String w3name)957 CreateTyp (
958 Widget form,
959 fields findex,
960 String w1name,
961 String w2name,
962 String w3name)
963 {
964 Widget wids[3];
965 char buf[10];
966
967 wids[0] = XtCreateWidget (w1name, labelWidgetClass, form, NULL, 0);
968 if (findex >= PixelClock && findex <= VSyncRate)
969 (void) snprintf(buf, sizeof(buf), "%6.2f",
970 (float)AppRes.field[findex].val / 1000.0);
971 else
972 (void) snprintf (buf, sizeof(buf), "%5d", AppRes.field[findex].val);
973 wids[1] = XtVaCreateWidget (w2name, labelWidgetClass,
974 form, XtNlabel, buf, NULL);
975 if (w3name != NULL) {
976 wids[2] = XtCreateWidget (w3name, scrollbarWidgetClass, form, NULL, 0);
977 XtAddCallback (wids[2], XtNjumpProc, ScrollCB, (XtPointer) findex);
978 XtManageChildren (wids, 3);
979 } else {
980 wids[2] = (Widget) NULL;
981 XtManageChildren (wids, 2);
982 }
983 AppRes.field[findex].textwidget = wids[1];
984 AppRes.field[findex].scrollwidget = wids[2];
985 }
986
987
988 static void
AckWarn(Widget w,XtPointer client,XtPointer call)989 AckWarn (Widget w, XtPointer client, XtPointer call)
990 {
991 XtPopdown((Widget) client);
992 XtDestroyWidget((Widget) client);
993 }
994
995 static void
AckNoTune(Widget w,XtPointer client,XtPointer call)996 AckNoTune (Widget w, XtPointer client, XtPointer call)
997 {
998 CleanUp(XtDisplay(w));
999 #if XtSpecificationRelease < 6
1000 exit (0);
1001 #else
1002 XtAppSetExitFlag (XtWidgetToApplicationContext (w));
1003 #endif
1004 }
1005
1006 static void
displayWarning(Widget top)1007 displayWarning(Widget top)
1008 {
1009 Widget w, popup, popupBox;
1010 int x, y;
1011
1012 x = DisplayWidth(XtDisplay (top),DefaultScreen (XtDisplay (top))) / 3;
1013 y = DisplayHeight(XtDisplay (top),DefaultScreen (XtDisplay (top))) / 3;
1014
1015 popup = XtVaCreatePopupShell("Warning",
1016 transientShellWidgetClass, top,
1017 XtNtitle, "WARNING",
1018 XtNx, x,
1019 XtNy, y,
1020 NULL);
1021
1022 popupBox = XtVaCreateManagedWidget(
1023 "WarningBox",
1024 boxWidgetClass,
1025 popup,
1026 NULL);
1027
1028 w = XtVaCreateManagedWidget( "WarnLabel",
1029 labelWidgetClass,
1030 popupBox,
1031 NULL);
1032
1033 w = XtVaCreateManagedWidget( "WarnOK",
1034 commandWidgetClass,
1035 popupBox,
1036 NULL);
1037
1038 XtAddCallback (w, XtNcallback, AckWarn, (XtPointer)popup);
1039
1040 w = XtVaCreateManagedWidget( "WarnCancel",
1041 commandWidgetClass,
1042 popupBox,
1043 NULL);
1044 XtAddCallback (w, XtNcallback, QuitCB, (XtPointer)NULL);
1045
1046 XtPopup(popup, XtGrabExclusive);
1047
1048 }
1049
1050 static void
displayNoTune(Widget top)1051 displayNoTune(Widget top)
1052 {
1053 Widget w, popup, popupBox;
1054
1055 popup = XtCreateWidget ("Notice", formWidgetClass, top, NULL, 0);
1056 popupBox = XtVaCreateManagedWidget(
1057 "WarningBox",
1058 boxWidgetClass,
1059 popup,
1060 NULL);
1061
1062 w = XtVaCreateManagedWidget( "NoTuneLabel",
1063 labelWidgetClass,
1064 popupBox,
1065 NULL);
1066
1067 w = XtVaCreateManagedWidget( "NoTuneOK",
1068 commandWidgetClass,
1069 popupBox,
1070 NULL);
1071
1072 XtAddCallback (w, XtNcallback, AckNoTune, (XtPointer)popup);
1073
1074 XtManageChild (popup);
1075 }
1076
1077 #if 0
1078 static void
1079 s3Special(Widget top)
1080 {
1081 Widget w, popup, form, invert_vclk_toggle, wids[6];
1082 char buf1[5] = {'\0',};
1083 int x, y;
1084
1085 x = DisplayWidth(XtDisplay (top),DefaultScreen (XtDisplay (top))) / 3;
1086 y = DisplayHeight(XtDisplay (top),DefaultScreen (XtDisplay (top))) / 3;
1087
1088 popup = XtVaCreatePopupShell("S3Adjust",
1089 transientShellWidgetClass, top,
1090 XtNtitle, "S3Adjust",
1091 XtNx, x,
1092 XtNy, y,
1093 NULL);
1094
1095 form = XtVaCreateManagedWidget(
1096 "S3Box",
1097 formWidgetClass,
1098 popup,
1099 NULL);
1100
1101 w = XtVaCreateManagedWidget( "S3Title",
1102 labelWidgetClass,
1103 form,
1104 NULL);
1105
1106 invert_vclk_toggle = XtVaCreateManagedWidget( "InvertVclk-toggle",
1107 toggleWidgetClass,
1108 form,
1109 NULL);
1110
1111 wids[0] = XtCreateWidget ("Blank1-label", labelWidgetClass,
1112 form, NULL, 0);
1113 wids[1] = XtVaCreateWidget ("Blank1-text", asciiTextWidgetClass,
1114 form, XtNstring, buf1, NULL);
1115 AddCallback (wids[1], XtNcallback, FlagsEditCB, (XtPointer) NULL);
1116
1117 XtManageChildren (wids, 2);
1118
1119 XtPopup(popup, XtGrabNone);
1120
1121 }
1122 #endif
1123
1124
1125
1126 static void
CreateHierarchy(Widget top)1127 CreateHierarchy(Widget top)
1128 {
1129 char buf[5];
1130 Widget form, forms[14], s3form;
1131 Widget wids[10];
1132 Widget boxW, popdownW, w;
1133 int i;
1134 int x, y;
1135 static String form_names[] = {
1136 "HDisplay-form",
1137 "HSyncStart-form",
1138 "HSyncEnd-form",
1139 "HTotal-form",
1140 "VDisplay-form",
1141 "VSyncStart-form",
1142 "VSyncEnd-form",
1143 "VTotal-form",
1144 "Flags-form",
1145 "Buttons-form",
1146 "PixelClock-form",
1147 "HSyncRate-form",
1148 "VSyncRate-form",
1149 "Buttons2-form",
1150 };
1151
1152 form = XtCreateWidget ("form", formWidgetClass, top, NULL, 0);
1153 for (i = 0; i < 14; i++)
1154 forms[i] = XtCreateWidget (form_names[i], formWidgetClass,
1155 form, NULL, 0);
1156
1157 CreateTyp (forms[0], HDisplay, "HDisplay-label", "HDisplay-text", NULL);
1158 CreateTyp (forms[1], HSyncStart, "HSyncStart-label",
1159 "HSyncStart-text", "HSyncStart-scrollbar");
1160 CreateTyp (forms[2], HSyncEnd, "HSyncEnd-label", "HSyncEnd-text",
1161 "HSyncEnd-scrollbar");
1162 CreateTyp (forms[3], HTotal, "HTotal-label", "HTotal-text",
1163 "HTotal-scrollbar");
1164
1165 w = XtVaCreateManagedWidget(
1166 "Left-button",
1167 commandWidgetClass,
1168 forms[3],
1169 NULL);
1170 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)HSyncStart);
1171 w = XtVaCreateManagedWidget(
1172 "Right-button",
1173 commandWidgetClass,
1174 forms[3],
1175 NULL);
1176 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)-HSyncStart);
1177 w= XtVaCreateManagedWidget(
1178 "Wider-button",
1179 commandWidgetClass,
1180 forms[3],
1181 NULL);
1182 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)-HTotal);
1183 w = XtVaCreateManagedWidget(
1184 "Narrower-button",
1185 commandWidgetClass,
1186 forms[3],
1187 NULL);
1188 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)HTotal);
1189 CreateTyp (forms[4], VDisplay, "VDisplay-label", "VDisplay-text", NULL);
1190 CreateTyp (forms[5], VSyncStart, "VSyncStart-label",
1191 "VSyncStart-text", "VSyncStart-scrollbar");
1192 CreateTyp (forms[6], VSyncEnd, "VSyncEnd-label", "VSyncEnd-text",
1193 "VSyncEnd-scrollbar");
1194 CreateTyp (forms[7], VTotal, "VTotal-label", "VTotal-text",
1195 "VTotal-scrollbar");
1196 w = XtVaCreateManagedWidget(
1197 "Up-button",
1198 commandWidgetClass,
1199 forms[7],
1200 NULL);
1201 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)VSyncStart);
1202 w = XtVaCreateManagedWidget(
1203 "Down-button",
1204 commandWidgetClass,
1205 forms[7],
1206 NULL);
1207 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)-VSyncStart);
1208 w= XtVaCreateManagedWidget(
1209 "Shorter-button",
1210 commandWidgetClass,
1211 forms[7],
1212 NULL);
1213 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)VTotal);
1214 w = XtVaCreateManagedWidget(
1215 "Taller-button",
1216 commandWidgetClass,
1217 forms[7],
1218 NULL);
1219 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)-VTotal);
1220
1221 (void) snprintf (buf, sizeof(buf), "%04x", AppRes.field[Flags].val);
1222 wids[0] = XtCreateWidget ("Flags-label", labelWidgetClass,
1223 forms[8], NULL, 0);
1224 wids[1] = XtVaCreateWidget ("Flags-text", asciiTextWidgetClass,
1225 forms[8], XtNstring, buf, XtNtranslations, trans, NULL);
1226 AddCallback (wids[1], XtNcallback, FlagsEditCB, (XtPointer) Flags);
1227 XtManageChildren (wids, 2);
1228 AppRes.field[Flags].textwidget = wids[1];
1229
1230 wids[0] = XtCreateWidget ("Quit-button", commandWidgetClass,
1231 forms[9], NULL, 0);
1232 XtAddCallback (wids[0], XtNcallback, QuitCB, NULL);
1233
1234 wids[1] = XtCreateWidget ("Apply-button", commandWidgetClass,
1235 forms[9], NULL, 0);
1236 XtAddCallback (wids[1], XtNcallback, ApplyCB, NULL);
1237
1238 wids[2] = XtCreateWidget ("AutoApply-toggle", toggleWidgetClass,
1239 forms[9], NULL, 0);
1240 auto_apply_toggle = wids[2];
1241
1242 wids[3] = XtCreateWidget ("Test-button", commandWidgetClass,
1243 forms[9], NULL, 0);
1244 XtAddCallback (wids[3], XtNcallback, TestCB, NULL);
1245
1246 wids[4] = XtCreateWidget ("Restore-button", commandWidgetClass,
1247 forms[9], NULL, 0);
1248 XtAddCallback (wids[4], XtNcallback, RestoreCB, NULL);
1249
1250 XtManageChildren (wids, 5);
1251
1252
1253 CreateTyp (forms[10], PixelClock, "PixelClock-label", "PixelClock-text",
1254 NULL);
1255 CreateTyp (forms[11], HSyncRate, "HSyncRate-label", "HSyncRate-text",
1256 NULL);
1257 CreateTyp (forms[12], VSyncRate, "VSyncRate-label", "VSyncRate-text",
1258 NULL);
1259
1260 wids[0] = XtCreateWidget ("Fetch-button", commandWidgetClass,
1261 forms[13], NULL, 0);
1262 XtAddCallback (wids[0], XtNcallback, FetchCB, NULL);
1263
1264 wids[1] = XtCreateWidget ("Show-button", commandWidgetClass,
1265 forms[13], NULL, 0);
1266 XtAddCallback (wids[1], XtNcallback, ShowCB, NULL);
1267
1268 wids[2] = XtCreateWidget ("Next-button", commandWidgetClass,
1269 forms[13], NULL, 0);
1270 XtAddCallback (wids[2], XtNcallback, SwitchCB, (XtPointer)1);
1271
1272 wids[3] = XtCreateWidget ("Prev-button", commandWidgetClass,
1273 forms[13], NULL, 0);
1274 XtAddCallback (wids[3], XtNcallback, SwitchCB, (XtPointer)-1);
1275
1276 XtManageChildren (wids, 4);
1277
1278 XtManageChildren (forms, 14);
1279
1280 if (S3Specials) {
1281 s3form = XtCreateWidget ("S3-form", formWidgetClass,
1282 form, NULL, 0);
1283 wids[0] = XtVaCreateWidget("InvertVclk-toggle", toggleWidgetClass,
1284 s3form, XtNstate, AppRes.field[InvertVclk].val, NULL);
1285 XtAddCallback (wids[0], XtNcallback, ApplyIfAutoCB, NULL);
1286 AppRes.field[InvertVclk].textwidget = wids[0];
1287 wids[1] = XtVaCreateWidget("EarlySc-toggle", toggleWidgetClass,
1288 s3form, XtNstate, AppRes.field[EarlySc].val, NULL);
1289 XtAddCallback (wids[1], XtNcallback, ApplyIfAutoCB, NULL);
1290 AppRes.field[EarlySc].textwidget = wids[1];
1291 wids[2] = XtCreateWidget("Blank1-label", labelWidgetClass, s3form,
1292 NULL, 0);
1293 wids[3] = XtVaCreateWidget("Blank1Dec-button", commandWidgetClass,
1294 s3form, NULL);
1295 XtAddCallback (wids[3], XtNcallback, ChangeBlankCB,
1296 (XtPointer)-BlankDelay1);
1297 (void) snprintf (buf, sizeof(buf), "%d", AppRes.field[BlankDelay1].val);
1298 wids[4] = XtVaCreateWidget("Blank1-text", asciiTextWidgetClass,
1299 s3form, XtNstring, buf, XtNtranslations, trans, NULL);
1300 AddCallback(wids[4], XtNcallback, BlankEditCB, (XPointer) BlankDelay1);
1301 AppRes.field[BlankDelay1].textwidget = wids[4];
1302 wids[5] = XtVaCreateWidget("Blank1Inc-button", commandWidgetClass,
1303 s3form, NULL);
1304 XtAddCallback (wids[5], XtNcallback, ChangeBlankCB,
1305 (XtPointer)BlankDelay1);
1306
1307 wids[6] = XtCreateWidget("Blank2-label", labelWidgetClass, s3form,
1308 NULL, 0);
1309 wids[7] = XtVaCreateWidget("Blank2Dec-button", commandWidgetClass,
1310 s3form, NULL);
1311 XtAddCallback (wids[7], XtNcallback, ChangeBlankCB,
1312 (XtPointer)-BlankDelay2);
1313 (void) snprintf (buf, sizeof(buf), "%d", AppRes.field[BlankDelay2].val);
1314 wids[8] = XtVaCreateWidget("Blank2-text", asciiTextWidgetClass,
1315 s3form, XtNstring, buf, XtNtranslations, trans, NULL);
1316 AddCallback(wids[8], XtNcallback, BlankEditCB, (XPointer) BlankDelay2);
1317 AppRes.field[BlankDelay2].textwidget = wids[8];
1318 wids[9] = XtVaCreateWidget("Blank2Inc-button", commandWidgetClass,
1319 s3form, NULL);
1320 XtAddCallback (wids[9], XtNcallback, ChangeBlankCB,
1321 (XtPointer)BlankDelay2);
1322 XtManageChildren (wids, 10);
1323 XtManageChild(s3form);
1324 }
1325
1326 XtManageChild (form);
1327
1328 SetScrollbars ();
1329 x = DisplayWidth(XtDisplay (top),DefaultScreen (XtDisplay (top))) / 2;
1330 y = DisplayHeight(XtDisplay (top),DefaultScreen (XtDisplay (top))) / 2;
1331
1332 invalid_mode_popup = XtVaCreatePopupShell("invalidMode",
1333 transientShellWidgetClass, top,
1334 XtNtitle, "Invalid Mode requested",
1335 XtNx, x - 20,
1336 XtNy, y - 40,
1337 NULL);
1338
1339 testing_popup = XtVaCreatePopupShell("testing",
1340 transientShellWidgetClass, top,
1341 XtNtitle, "Testing_1_2_3",
1342 XtNx, x - 20,
1343 XtNy, y - 40,
1344 NULL);
1345 boxW = XtVaCreateManagedWidget(
1346 "TestingBox",
1347 boxWidgetClass,
1348 testing_popup,
1349 NULL);
1350
1351 w = XtVaCreateManagedWidget(
1352 "testingMessage",
1353 labelWidgetClass,
1354 boxW,
1355 NULL);
1356
1357 w = XtVaCreateManagedWidget(
1358 "Abort",
1359 commandWidgetClass,
1360 boxW,
1361 NULL);
1362
1363 XtAddCallback (w, XtNcallback, (XtCallbackProc) TestTOCB,
1364 (XtPointer) NULL);
1365
1366 boxW = XtVaCreateManagedWidget(
1367 "invalidBox",
1368 boxWidgetClass,
1369 invalid_mode_popup,
1370 NULL);
1371
1372 (void) XtVaCreateManagedWidget(
1373 "ErrorMessage",
1374 labelWidgetClass,
1375 boxW,
1376 NULL);
1377
1378 popdownW = XtVaCreateManagedWidget(
1379 "AckError",
1380 commandWidgetClass,
1381 boxW,
1382 NULL);
1383
1384 XtAddCallback (popdownW, XtNcallback, (XtCallbackProc)popdownInvalid,
1385 (XtPointer) invalid_mode_popup);
1386 }
1387
1388 static void
QuitAction(Widget w,XEvent * e,String * vector,Cardinal * count)1389 QuitAction (Widget w, XEvent* e, String* vector, Cardinal* count)
1390 {
1391 if ((e->type == ClientMessage
1392 && e->xclient.data.l[0] == (long) wm_delete_window)
1393 || e->type == KeyPress)
1394 QuitCB(w, NULL, NULL);
1395 }
1396
1397 static void
RestoreAction(Widget w,XEvent * e,String * vector,Cardinal * count)1398 RestoreAction (Widget w, XEvent* e, String* vector, Cardinal* count)
1399 {
1400 Boolean state;
1401
1402 RestoreCB(w, NULL, NULL);
1403 XtVaGetValues(auto_apply_toggle, XtNstate, &state, NULL);
1404 if (!state)
1405 ApplyCB (w, NULL, NULL);
1406 }
1407
1408
1409 static void
ShowAction(Widget w,XEvent * e,String * vector,Cardinal * count)1410 ShowAction(Widget w, XEvent* e, String* vector, Cardinal* count)
1411 {
1412 ShowCB(w, NULL, NULL);
1413 }
1414
1415 static void
MoveLeftAction(Widget w,XEvent * e,String * vector,Cardinal * count)1416 MoveLeftAction(Widget w, XEvent* e, String* vector, Cardinal* count)
1417 {
1418 AdjustCB(w, (XtPointer)HSyncStart, NULL);
1419 }
1420
1421 static void
MoveRightAction(Widget w,XEvent * e,String * vector,Cardinal * count)1422 MoveRightAction(Widget w, XEvent* e, String* vector, Cardinal* count)
1423 {
1424 AdjustCB(w, (XtPointer)-HSyncStart, NULL);
1425 }
1426
1427 static void
NarrowerAction(Widget w,XEvent * e,String * vector,Cardinal * count)1428 NarrowerAction(Widget w, XEvent* e, String* vector, Cardinal* count)
1429 {
1430 AdjustCB(w, (XtPointer)HTotal, NULL);
1431 }
1432
1433 static void
WiderAction(Widget w,XEvent * e,String * vector,Cardinal * count)1434 WiderAction(Widget w, XEvent* e, String* vector, Cardinal* count)
1435 {
1436 AdjustCB(w, (XtPointer)-HTotal, NULL);
1437 }
1438
1439 static void
MoveUpAction(Widget w,XEvent * e,String * vector,Cardinal * count)1440 MoveUpAction(Widget w, XEvent* e, String* vector, Cardinal* count)
1441 {
1442 AdjustCB(w, (XtPointer)VSyncStart, NULL);
1443 }
1444
1445 static void
MoveDownAction(Widget w,XEvent * e,String * vector,Cardinal * count)1446 MoveDownAction(Widget w, XEvent* e, String* vector, Cardinal* count)
1447 {
1448 AdjustCB(w, (XtPointer)-VSyncStart, NULL);
1449 }
1450
1451 static void
TallerAction(Widget w,XEvent * e,String * vector,Cardinal * count)1452 TallerAction(Widget w, XEvent* e, String* vector, Cardinal* count)
1453 {
1454 AdjustCB(w, (XtPointer)-VTotal, NULL);
1455 }
1456
1457 static void
ShorterAction(Widget w,XEvent * e,String * vector,Cardinal * count)1458 ShorterAction(Widget w, XEvent* e, String* vector, Cardinal* count)
1459 {
1460 AdjustCB(w, (XtPointer)VTotal, NULL);
1461 }
1462
1463 static void
NextModeAction(Widget w,XEvent * e,String * vector,Cardinal * count)1464 NextModeAction(Widget w, XEvent* e, String* vector, Cardinal* count)
1465 {
1466 SwitchCB(w, (XPointer) 1, NULL);
1467 }
1468
1469 static void
PrevModeAction(Widget w,XEvent * e,String * vector,Cardinal * count)1470 PrevModeAction(Widget w, XEvent* e, String* vector, Cardinal* count)
1471 {
1472 SwitchCB(w, (XPointer) -1, NULL);
1473 }
1474
1475
1476
1477 static void
usage(void)1478 usage(void)
1479 {
1480 fprintf(stderr, "Usage: xvidtune [option]\n");
1481 fprintf(stderr, " where option is one of:\n");
1482 fprintf(stderr, " -show Print current modeline to stdout\n");
1483 fprintf(stderr, " -next Switch to next video mode\n");
1484 fprintf(stderr, " -prev Switch to previous video mode\n");
1485 fprintf(stderr, " -unlock Enable mode switch hot-keys\n");
1486 fprintf(stderr, " -timeout [seconds] Set testmode timeout in seconds,\n");
1487 exit(1);
1488 }
1489
1490
1491 int
main(int argc,char ** argv)1492 main (int argc, char** argv)
1493 {
1494 Widget top;
1495 XtAppContext app;
1496 Display* dpy;
1497 Bool modeSettable = TRUE;
1498
1499 static XtActionsRec actions[] = { { "xvidtune-quit", QuitAction },
1500 { "xvidtune-restore", RestoreAction },
1501 { "xvidtune-show", ShowAction },
1502 { "xvidtune-moveleft", MoveLeftAction },
1503 { "xvidtune-moveright", MoveRightAction },
1504 { "xvidtune-wider", WiderAction },
1505 { "xvidtune-narrower", NarrowerAction },
1506 { "xvidtune-moveup", MoveUpAction },
1507 { "xvidtune-movedown", MoveDownAction },
1508 { "xvidtune-taller", TallerAction },
1509 { "xvidtune-shorter", ShorterAction },
1510 { "xvidtune-nextmode", NextModeAction },
1511 { "xvidtune-prevmode", PrevModeAction } };
1512
1513 Top = top = XtVaOpenApplication (&app, "Xvidtune", NULL, 0, &argc, argv,
1514 NULL, applicationShellWidgetClass,
1515 XtNmappedWhenManaged, False, NULL);
1516
1517 XtGetApplicationResources (top, (XtPointer)&AppRes,
1518 Resources, XtNumber(Resources),
1519 NULL, 0);
1520
1521 if (!AppRes.ad_installed) {
1522 fprintf(stderr, "Please install the program before using\n");
1523 return 3;
1524 }
1525
1526 if (!XF86VidModeQueryVersion(XtDisplay (top), &MajorVersion, &MinorVersion)) {
1527 fprintf(stderr, "Unable to query video extension version\n");
1528 return 2;
1529 }
1530
1531 if (!XF86VidModeQueryExtension(XtDisplay (top), &EventBase, &ErrorBase)) {
1532 fprintf(stderr, "Unable to query video extension information\n");
1533 return 2;
1534 }
1535
1536 /* Fail if the extension version in the server is too old */
1537 if (MajorVersion < MINMAJOR ||
1538 (MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) {
1539 fprintf(stderr,
1540 "Xserver is running an old XFree86-VidModeExtension version"
1541 " (%d.%d)\n", MajorVersion, MinorVersion);
1542 fprintf(stderr, "Minimum required version is %d.%d\n",
1543 MINMAJOR, MINMINOR);
1544 exit(2);
1545 }
1546
1547 /* This should probably be done differently */
1548
1549 if( argc == 3 ) { /* this can only be the timeout case */
1550 if( (!strcmp(argv[1], "-timeout")) ) {
1551 TestTimeout = ((unsigned long) atol( argv[2] )) * 1000L;
1552 }
1553 else
1554 usage();
1555 }
1556
1557 if (argc > 1) {
1558 int i = 0;
1559
1560 if (argc != 2)
1561 usage();
1562 if (!strcmp(argv[1], "-show")) {
1563 if (!GetModeLine(XtDisplay (top), DefaultScreen (XtDisplay (top)))) {
1564 fprintf(stderr, "Unable to get mode info\n");
1565 CleanUp(XtDisplay (top));
1566 return 2;
1567 }
1568 ShowCB(top, NULL, NULL);
1569 return 0;
1570 } else if (!strcmp(argv[1], "-next"))
1571 i = 1;
1572 else if (!strcmp(argv[1], "-prev"))
1573 i = -1;
1574 else if (!strcmp(argv[1], "-unlock")) {
1575 CleanUp(XtDisplay (top));
1576 XSync(XtDisplay (top), True);
1577 return 0;
1578 } else
1579 usage();
1580 if (i != 0) {
1581 XF86VidModeSwitchMode(XtDisplay (top),
1582 DefaultScreen (XtDisplay (top)), i);
1583 XSync(XtDisplay (top), True);
1584 return 0;
1585 }
1586 }
1587 if (!GetMonitor(XtDisplay (top), DefaultScreen (XtDisplay (top)))) {
1588 fprintf(stderr, "Unable to query monitor info\n");
1589 return 2;
1590 }
1591
1592 if (!XF86VidModeLockModeSwitch(XtDisplay (top),
1593 DefaultScreen (XtDisplay (top)), TRUE)) {
1594 fprintf(stderr, "Failed to disable mode-switch hot-keys\n");
1595 return 2;
1596 }
1597
1598 signal(SIGINT, CatchSig);
1599 signal(SIGQUIT, CatchSig);
1600 signal(SIGTERM, CatchSig);
1601 signal(SIGHUP, CatchSig);
1602 sigId = XtAppAddSignal(app, CatchXtSig, NULL);
1603
1604 if (!GetModeLine(XtDisplay (top), DefaultScreen (XtDisplay (top)))) {
1605 fprintf(stderr, "Unable to get mode info\n");
1606 CleanUp(XtDisplay (top));
1607 return 2;
1608 }
1609
1610 xtErrorfunc = XSetErrorHandler(vidmodeError);
1611
1612 trans = XtParseTranslationTable ("\
1613 <Key>0: insert-char()\n<Key>1: insert-char()\n\
1614 <Key>2: insert-char()\n<Key>3: insert-char()\n\
1615 <Key>4: insert-char()\n<Key>5: insert-char()\n\
1616 <Key>6: insert-char()\n<Key>7: insert-char()\n\
1617 <Key>8: insert-char()\n<Key>9: insert-char()\n\
1618 <Key>a: insert-char()\n<Key>b: insert-char()\n\
1619 <Key>c: insert-char()\n<Key>d: insert-char()\n\
1620 <Key>e: insert-char()\n<Key>f: insert-char()\n\
1621 <Key>+: insert-char()\n<Key>-: insert-char()\n\
1622 <Key>r: xvidtune-restore()\n<Key>q: xvidtune-quit()\n\
1623 <Key>BackSpace: delete-previous-character()\n\
1624 <Key>Right: forward-character()\n<Key>KP_Right: forward-character()\n\
1625 <Key>Left: backward-character()\n<Key>KP_Left: backward-character()\n\
1626 <Key>Delete: delete-previous-character()\n\
1627 <Key>KP_Delete: delete-previous-character()\n\
1628 <EnterWindow>: enter-window()\n<LeaveWindow>: leave-window()\n\
1629 <FocusIn>: focus-in()\n<FocusOut>: focus-out()\n\
1630 <Btn1Down>: select-start()\n");
1631
1632 if (!ModeSettable()) {
1633 printf("Video modes are not settable on this chip\n");
1634 displayNoTune(top);
1635 modeSettable = FALSE;
1636 } else
1637 CreateHierarchy (top);
1638
1639
1640 XtAppAddActions (app, actions, XtNumber(actions));
1641
1642 XtOverrideTranslations (top,
1643 XtParseTranslationTable ("<Message>WM_PROTOCOLS: xvidtune-quit()"));
1644
1645 XtRealizeWidget (top);
1646
1647 dpy = XtDisplay(top);
1648
1649 wm_delete_window = XInternAtom (dpy, "WM_DELETE_WINDOW", False);
1650
1651 (void) XSetWMProtocols (dpy, XtWindow (top), &wm_delete_window, 1);
1652
1653 XtMapWidget (top);
1654
1655 if (modeSettable)
1656 displayWarning(top);
1657
1658 /* really we should run our own event dispatching here until the
1659 * warning has been read...
1660 */
1661 XtAppMainLoop (app);
1662
1663 return 0;
1664 }
1665