xvidtune.c revision 14ddf674
1/* $XFree86: xc/programs/xvidtune/xvidtune.c,v 3.35tsi Exp $ */ 2 3/* 4 5Copyright (c) 1995 Kaleb S. KEITHLEY 6 7Permission is hereby granted, free of charge, to any person obtaining 8a copy of this software and associated documentation files (the 9"Software"), to deal in the Software without restriction, including 10without limitation the rights to use, copy, modify, merge, publish, 11distribute, sublicense, and/or sell copies of the Software, and to 12permit persons to whom the Software is furnished to do so, subject to 13the following conditions: 14 15The above copyright notice and this permission notice shall be 16included in all copies or substantial portions of the Software. 17 18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21IN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES 22OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24OTHER DEALINGS IN THE SOFTWARE. 25 26Except as contained in this notice, the name of Kaleb S. KEITHLEY 27shall not be used in advertising or otherwise to promote the sale, use 28or other dealings in this Software without prior written authorization 29from 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 52static int MajorVersion, MinorVersion; 53static int EventBase, ErrorBase; 54static int dot_clock, mode_flags; 55static unsigned long TestTimeout=5000; /* Default test timeout */ 56static 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 74typedef enum { HDisplay, HSyncStart, HSyncEnd, HTotal, 75 VDisplay, VSyncStart, VSyncEnd, VTotal, Flags, 76 InvertVclk, BlankDelay1, BlankDelay2, EarlySc, 77 PixelClock, HSyncRate, VSyncRate, fields_num } fields; 78 79typedef 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 89static 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 115static 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 139static XtTranslations trans; 140 141static Atom wm_delete_window; 142static Widget invalid_mode_popup; 143static Widget testing_popup; 144static Widget Top; 145static Widget auto_apply_toggle; 146 147static Bool S3Specials = False; 148static char modebuf[160]; 149 150static void UpdateSyncRates(Bool dolabels); 151 152static void 153CleanUp(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 160static void 161CatchSig(int signal) 162{ 163 XtNoticeSignal(sigId); 164} 165 166static void 167CatchXtSig(XtPointer closure, XtSignalId *id) 168{ 169 CleanUp(XtDisplay(Top)); 170 exit(3); 171} 172 173static Bool 174GetModeLine (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 207static Bool 208GetMonitor (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 229static Bool 230ModeSettable(void) 231{ 232 if (AppRes.field[HTotal].val == 0 || AppRes.field[VTotal].val == 0) 233 return FALSE; 234 return TRUE; 235} 236 237static int hitError = 0; 238static int (*xtErrorfunc)(Display *, XErrorEvent *); 239 240static int 241vidmodeError(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 255static void 256SetScrollbars (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 275static void 276QuitCB (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 286static void 287popdownInvalid(Widget w, XtPointer client, XtPointer call) 288{ 289 XtPopdown((Widget)client); 290} 291 292static void 293ApplyCB (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 353static void 354SetLabel(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 408static void 409UpdateSyncRates(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 428static void 429RestoreCB (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 445static void 446ApplyIfAutoCB (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 456static void 457FetchCB (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 467static XtIntervalId TOid; 468 469static void 470TestTO (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 485static void 486TestTOCB (Widget w, XtPointer client, XtPointer call) 487{ 488 XtRemoveTimeOut(TOid); 489 TestTO(w, (XtIntervalId *) NULL); 490} 491 492static void 493TestCB (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 507static Boolean 508ConvertSelection( 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 529static void 530ShowCB(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 595static void 596AdjustCB(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 673static void 674EditCB (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 746static void 747FlagsEditCB (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 773static void 774BlankEditCB (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 821static void 822ChangeBlankCB (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 859static int 860isValid(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 895static void 896ScrollCB (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 931static void 932SwitchCB (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 943static void 944AddCallback ( 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 956static void 957CreateTyp ( 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 988static void 989AckWarn (Widget w, XtPointer client, XtPointer call) 990{ 991 XtPopdown((Widget) client); 992 XtDestroyWidget((Widget) client); 993} 994 995static void 996AckNoTune (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 1006static void 1007displayWarning(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 1050static void 1051displayNoTune(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 1078static void 1079s3Special(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 1126static void 1127CreateHierarchy(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 char buf[2] = "0"; 1282 s3form = XtCreateWidget ("S3-form", formWidgetClass, 1283 form, NULL, 0); 1284 wids[0] = XtVaCreateWidget("InvertVclk-toggle", toggleWidgetClass, 1285 s3form, XtNstate, AppRes.field[InvertVclk].val, NULL); 1286 XtAddCallback (wids[0], XtNcallback, ApplyIfAutoCB, NULL); 1287 AppRes.field[InvertVclk].textwidget = wids[0]; 1288 wids[1] = XtVaCreateWidget("EarlySc-toggle", toggleWidgetClass, 1289 s3form, XtNstate, AppRes.field[EarlySc].val, NULL); 1290 XtAddCallback (wids[1], XtNcallback, ApplyIfAutoCB, NULL); 1291 AppRes.field[EarlySc].textwidget = wids[1]; 1292 wids[2] = XtCreateWidget("Blank1-label", labelWidgetClass, s3form, 1293 NULL, 0); 1294 wids[3] = XtVaCreateWidget("Blank1Dec-button", commandWidgetClass, 1295 s3form, NULL); 1296 XtAddCallback (wids[3], XtNcallback, ChangeBlankCB, 1297 (XtPointer)-BlankDelay1); 1298 (void) snprintf (buf, sizeof(buf), "%d", AppRes.field[BlankDelay1].val); 1299 wids[4] = XtVaCreateWidget("Blank1-text", asciiTextWidgetClass, 1300 s3form, XtNstring, buf, XtNtranslations, trans, NULL); 1301 AddCallback(wids[4], XtNcallback, BlankEditCB, (XPointer) BlankDelay1); 1302 AppRes.field[BlankDelay1].textwidget = wids[4]; 1303 wids[5] = XtVaCreateWidget("Blank1Inc-button", commandWidgetClass, 1304 s3form, NULL); 1305 XtAddCallback (wids[5], XtNcallback, ChangeBlankCB, 1306 (XtPointer)BlankDelay1); 1307 1308 wids[6] = XtCreateWidget("Blank2-label", labelWidgetClass, s3form, 1309 NULL, 0); 1310 wids[7] = XtVaCreateWidget("Blank2Dec-button", commandWidgetClass, 1311 s3form, NULL); 1312 XtAddCallback (wids[7], XtNcallback, ChangeBlankCB, 1313 (XtPointer)-BlankDelay2); 1314 (void) snprintf (buf, sizeof(buf), "%d", AppRes.field[BlankDelay2].val); 1315 wids[8] = XtVaCreateWidget("Blank2-text", asciiTextWidgetClass, 1316 s3form, XtNstring, buf, XtNtranslations, trans, NULL); 1317 AddCallback(wids[8], XtNcallback, BlankEditCB, (XPointer) BlankDelay2); 1318 AppRes.field[BlankDelay2].textwidget = wids[8]; 1319 wids[9] = XtVaCreateWidget("Blank2Inc-button", commandWidgetClass, 1320 s3form, NULL); 1321 XtAddCallback (wids[9], XtNcallback, ChangeBlankCB, 1322 (XtPointer)BlankDelay2); 1323 XtManageChildren (wids, 10); 1324 XtManageChild(s3form); 1325 } 1326 1327 XtManageChild (form); 1328 1329 SetScrollbars (); 1330 x = DisplayWidth(XtDisplay (top),DefaultScreen (XtDisplay (top))) / 2; 1331 y = DisplayHeight(XtDisplay (top),DefaultScreen (XtDisplay (top))) / 2; 1332 1333 invalid_mode_popup = XtVaCreatePopupShell("invalidMode", 1334 transientShellWidgetClass, top, 1335 XtNtitle, "Invalid Mode requested", 1336 XtNx, x - 20, 1337 XtNy, y - 40, 1338 NULL); 1339 1340 testing_popup = XtVaCreatePopupShell("testing", 1341 transientShellWidgetClass, top, 1342 XtNtitle, "Testing_1_2_3", 1343 XtNx, x - 20, 1344 XtNy, y - 40, 1345 NULL); 1346 boxW = XtVaCreateManagedWidget( 1347 "TestingBox", 1348 boxWidgetClass, 1349 testing_popup, 1350 NULL); 1351 1352 w = XtVaCreateManagedWidget( 1353 "testingMessage", 1354 labelWidgetClass, 1355 boxW, 1356 NULL); 1357 1358 w = XtVaCreateManagedWidget( 1359 "Abort", 1360 commandWidgetClass, 1361 boxW, 1362 NULL); 1363 1364 XtAddCallback (w, XtNcallback, (XtCallbackProc) TestTOCB, 1365 (XtPointer) NULL); 1366 1367 boxW = XtVaCreateManagedWidget( 1368 "invalidBox", 1369 boxWidgetClass, 1370 invalid_mode_popup, 1371 NULL); 1372 1373 (void) XtVaCreateManagedWidget( 1374 "ErrorMessage", 1375 labelWidgetClass, 1376 boxW, 1377 NULL); 1378 1379 popdownW = XtVaCreateManagedWidget( 1380 "AckError", 1381 commandWidgetClass, 1382 boxW, 1383 NULL); 1384 1385 XtAddCallback (popdownW, XtNcallback, (XtCallbackProc)popdownInvalid, 1386 (XtPointer) invalid_mode_popup); 1387} 1388 1389static void 1390QuitAction (Widget w, XEvent* e, String* vector, Cardinal* count) 1391{ 1392 if ((e->type == ClientMessage 1393 && e->xclient.data.l[0] == (long) wm_delete_window) 1394 || e->type == KeyPress) 1395 QuitCB(w, NULL, NULL); 1396} 1397 1398static void 1399RestoreAction (Widget w, XEvent* e, String* vector, Cardinal* count) 1400{ 1401 Boolean state; 1402 1403 RestoreCB(w, NULL, NULL); 1404 XtVaGetValues(auto_apply_toggle, XtNstate, &state, NULL); 1405 if (!state) 1406 ApplyCB (w, NULL, NULL); 1407} 1408 1409 1410static void 1411ShowAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1412{ 1413 ShowCB(w, NULL, NULL); 1414} 1415 1416static void 1417MoveLeftAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1418{ 1419 AdjustCB(w, (XtPointer)HSyncStart, NULL); 1420} 1421 1422static void 1423MoveRightAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1424{ 1425 AdjustCB(w, (XtPointer)-HSyncStart, NULL); 1426} 1427 1428static void 1429NarrowerAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1430{ 1431 AdjustCB(w, (XtPointer)HTotal, NULL); 1432} 1433 1434static void 1435WiderAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1436{ 1437 AdjustCB(w, (XtPointer)-HTotal, NULL); 1438} 1439 1440static void 1441MoveUpAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1442{ 1443 AdjustCB(w, (XtPointer)VSyncStart, NULL); 1444} 1445 1446static void 1447MoveDownAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1448{ 1449 AdjustCB(w, (XtPointer)-VSyncStart, NULL); 1450} 1451 1452static void 1453TallerAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1454{ 1455 AdjustCB(w, (XtPointer)-VTotal, NULL); 1456} 1457 1458static void 1459ShorterAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1460{ 1461 AdjustCB(w, (XtPointer)VTotal, NULL); 1462} 1463 1464static void 1465NextModeAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1466{ 1467 SwitchCB(w, (XPointer) 1, NULL); 1468} 1469 1470static void 1471PrevModeAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1472{ 1473 SwitchCB(w, (XPointer) -1, NULL); 1474} 1475 1476 1477 1478static void 1479usage(void) 1480{ 1481 fprintf(stderr, "Usage: xvidtune [option]\n"); 1482 fprintf(stderr, " where option is one of:\n"); 1483 fprintf(stderr, " -show Print current modeline to stdout\n"); 1484 fprintf(stderr, " -next Switch to next video mode\n"); 1485 fprintf(stderr, " -prev Switch to previous video mode\n"); 1486 fprintf(stderr, " -unlock Enable mode switch hot-keys\n"); 1487 fprintf(stderr, " -timeout [seconds] Set testmode timeout in seconds,\n"); 1488 exit(1); 1489} 1490 1491 1492int 1493main (int argc, char** argv) 1494{ 1495 Widget top; 1496 XtAppContext app; 1497 Display* dpy; 1498 Bool modeSettable = TRUE; 1499 1500 static XtActionsRec actions[] = { { "xvidtune-quit", QuitAction }, 1501 { "xvidtune-restore", RestoreAction }, 1502 { "xvidtune-show", ShowAction }, 1503 { "xvidtune-moveleft", MoveLeftAction }, 1504 { "xvidtune-moveright", MoveRightAction }, 1505 { "xvidtune-wider", WiderAction }, 1506 { "xvidtune-narrower", NarrowerAction }, 1507 { "xvidtune-moveup", MoveUpAction }, 1508 { "xvidtune-movedown", MoveDownAction }, 1509 { "xvidtune-taller", TallerAction }, 1510 { "xvidtune-shorter", ShorterAction }, 1511 { "xvidtune-nextmode", NextModeAction }, 1512 { "xvidtune-prevmode", PrevModeAction } }; 1513 1514 Top = top = XtVaOpenApplication (&app, "Xvidtune", NULL, 0, &argc, argv, 1515 NULL, applicationShellWidgetClass, 1516 XtNmappedWhenManaged, False, NULL); 1517 1518 XtGetApplicationResources (top, (XtPointer)&AppRes, 1519 Resources, XtNumber(Resources), 1520 NULL, 0); 1521 1522 if (!AppRes.ad_installed) { 1523 fprintf(stderr, "Please install the program before using\n"); 1524 return 3; 1525 } 1526 1527 if (!XF86VidModeQueryVersion(XtDisplay (top), &MajorVersion, &MinorVersion)) { 1528 fprintf(stderr, "Unable to query video extension version\n"); 1529 return 2; 1530 } 1531 1532 if (!XF86VidModeQueryExtension(XtDisplay (top), &EventBase, &ErrorBase)) { 1533 fprintf(stderr, "Unable to query video extension information\n"); 1534 return 2; 1535 } 1536 1537 /* Fail if the extension version in the server is too old */ 1538 if (MajorVersion < MINMAJOR || 1539 (MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) { 1540 fprintf(stderr, 1541 "Xserver is running an old XFree86-VidModeExtension version" 1542 " (%d.%d)\n", MajorVersion, MinorVersion); 1543 fprintf(stderr, "Minimum required version is %d.%d\n", 1544 MINMAJOR, MINMINOR); 1545 exit(2); 1546 } 1547 1548 /* This should probably be done differently */ 1549 1550 if( argc == 3 ) { /* this can only be the timeout case */ 1551 if( (!strcmp(argv[1], "-timeout")) ) { 1552 TestTimeout = ((unsigned long) atol( argv[2] )) * 1000L; 1553 } 1554 else 1555 usage(); 1556 } 1557 1558 if (argc > 1) { 1559 int i = 0; 1560 1561 if (argc != 2) 1562 usage(); 1563 if (!strcmp(argv[1], "-show")) { 1564 if (!GetModeLine(XtDisplay (top), DefaultScreen (XtDisplay (top)))) { 1565 fprintf(stderr, "Unable to get mode info\n"); 1566 CleanUp(XtDisplay (top)); 1567 return 2; 1568 } 1569 ShowCB(top, NULL, NULL); 1570 return 0; 1571 } else if (!strcmp(argv[1], "-next")) 1572 i = 1; 1573 else if (!strcmp(argv[1], "-prev")) 1574 i = -1; 1575 else if (!strcmp(argv[1], "-unlock")) { 1576 CleanUp(XtDisplay (top)); 1577 XSync(XtDisplay (top), True); 1578 return 0; 1579 } else 1580 usage(); 1581 if (i != 0) { 1582 XF86VidModeSwitchMode(XtDisplay (top), 1583 DefaultScreen (XtDisplay (top)), i); 1584 XSync(XtDisplay (top), True); 1585 return 0; 1586 } 1587 } 1588 if (!GetMonitor(XtDisplay (top), DefaultScreen (XtDisplay (top)))) { 1589 fprintf(stderr, "Unable to query monitor info\n"); 1590 return 2; 1591 } 1592 1593 if (!XF86VidModeLockModeSwitch(XtDisplay (top), 1594 DefaultScreen (XtDisplay (top)), TRUE)) { 1595 fprintf(stderr, "Failed to disable mode-switch hot-keys\n"); 1596 return 2; 1597 } 1598 1599 signal(SIGINT, CatchSig); 1600 signal(SIGQUIT, CatchSig); 1601 signal(SIGTERM, CatchSig); 1602 signal(SIGHUP, CatchSig); 1603 sigId = XtAppAddSignal(app, CatchXtSig, NULL); 1604 1605 if (!GetModeLine(XtDisplay (top), DefaultScreen (XtDisplay (top)))) { 1606 fprintf(stderr, "Unable to get mode info\n"); 1607 CleanUp(XtDisplay (top)); 1608 return 2; 1609 } 1610 1611 xtErrorfunc = XSetErrorHandler(vidmodeError); 1612 1613 trans = XtParseTranslationTable ("\ 1614 <Key>0: insert-char()\n<Key>1: insert-char()\n\ 1615 <Key>2: insert-char()\n<Key>3: insert-char()\n\ 1616 <Key>4: insert-char()\n<Key>5: insert-char()\n\ 1617 <Key>6: insert-char()\n<Key>7: insert-char()\n\ 1618 <Key>8: insert-char()\n<Key>9: insert-char()\n\ 1619 <Key>a: insert-char()\n<Key>b: insert-char()\n\ 1620 <Key>c: insert-char()\n<Key>d: insert-char()\n\ 1621 <Key>e: insert-char()\n<Key>f: insert-char()\n\ 1622 <Key>+: insert-char()\n<Key>-: insert-char()\n\ 1623 <Key>r: xvidtune-restore()\n<Key>q: xvidtune-quit()\n\ 1624 <Key>BackSpace: delete-previous-character()\n\ 1625 <Key>Right: forward-character()\n<Key>KP_Right: forward-character()\n\ 1626 <Key>Left: backward-character()\n<Key>KP_Left: backward-character()\n\ 1627 <Key>Delete: delete-previous-character()\n\ 1628 <Key>KP_Delete: delete-previous-character()\n\ 1629 <EnterWindow>: enter-window()\n<LeaveWindow>: leave-window()\n\ 1630 <FocusIn>: focus-in()\n<FocusOut>: focus-out()\n\ 1631 <Btn1Down>: select-start()\n"); 1632 1633 if (!ModeSettable()) { 1634 printf("Video modes are not settable on this chip\n"); 1635 displayNoTune(top); 1636 modeSettable = FALSE; 1637 } else 1638 CreateHierarchy (top); 1639 1640 1641 XtAppAddActions (app, actions, XtNumber(actions)); 1642 1643 XtOverrideTranslations (top, 1644 XtParseTranslationTable ("<Message>WM_PROTOCOLS: xvidtune-quit()")); 1645 1646 XtRealizeWidget (top); 1647 1648 dpy = XtDisplay(top); 1649 1650 wm_delete_window = XInternAtom (dpy, "WM_DELETE_WINDOW", False); 1651 1652 (void) XSetWMProtocols (dpy, XtWindow (top), &wm_delete_window, 1); 1653 1654 XtMapWidget (top); 1655 1656 if (modeSettable) 1657 displayWarning(top); 1658 1659 /* really we should run our own event dispatching here until the 1660 * warning has been read... 1661 */ 1662 XtAppMainLoop (app); 1663 1664 return 0; 1665} 1666