xvidtune.c revision cacd992d
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 52int MajorVersion, MinorVersion; 53int EventBase, ErrorBase; 54int dot_clock, mode_flags; 55unsigned long TestTimeout=5000; /* Default test timeout */ 56XtSignalId 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) sprintf (buf, "%04x", sdp->val); 374 else if (i >= PixelClock && i <= VSyncRate) 375 (void) sprintf (buf, "%6.2f", (float)sdp->val / 1000.0); 376 else if (i == BlankDelay1 || i == BlankDelay2) { 377 (void) sprintf (buf, "%d", sdp->val); 378 } else 379 (void) sprintf (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 sprintf(tmpbuf, "\"%dx%d\"", 536 AppRes.field[HDisplay].val, AppRes.field[VDisplay].val); 537 sprintf(modebuf, "%-11s %6.2f %4d %4d %4d %4d %4d %4d %4d %4d", 538 tmpbuf, (float)dot_clock/1000.0, 539 AppRes.field[HDisplay].val, 540 AppRes.field[HSyncStart].val, 541 AppRes.field[HSyncEnd].val, 542 AppRes.field[HTotal].val, 543 AppRes.field[VDisplay].val, 544 AppRes.field[VSyncStart].val, 545 AppRes.field[VSyncEnd].val, 546 AppRes.field[VTotal].val); 547 /* Print out the flags (if any) */ 548 if (mode_flags & V_PHSYNC) strcat(modebuf, " +hsync"); 549 if (mode_flags & V_NHSYNC) strcat(modebuf, " -hsync"); 550 if (mode_flags & V_PVSYNC) strcat(modebuf, " +vsync"); 551 if (mode_flags & V_NVSYNC) strcat(modebuf, " -vsync"); 552 if (mode_flags & V_INTERLACE) strcat(modebuf, " interlace"); 553 if (mode_flags & V_CSYNC) strcat(modebuf, " composite"); 554 if (mode_flags & V_PCSYNC) strcat(modebuf, " +csync"); 555 if (mode_flags & V_NCSYNC) strcat(modebuf, " -csync"); 556 if (mode_flags & V_DBLSCAN) strcat(modebuf, " doublescan"); 557 printf("%s\n", modebuf); 558 time = XtLastTimestampProcessed(XtDisplay(w)); 559 XtOwnSelection(w, XA_PRIMARY, time, ConvertSelection, NULL, NULL); 560 if (S3Specials) { 561 unsigned int i; 562 Boolean state; 563 char *string; 564 565 XtVaGetValues(AppRes.field[InvertVclk].textwidget, 566 XtNstate, &state, NULL); 567 AppRes.field[InvertVclk].val = state ? 1 : 0; 568 XtVaGetValues (AppRes.field[BlankDelay1].textwidget, 569 XtNstring, &string, NULL); 570 (void) sscanf (string, "%x", &i); 571 AppRes.field[BlankDelay1].val = i; 572 XtVaGetValues (AppRes.field[BlankDelay2].textwidget, 573 XtNstring, &string, NULL); 574 (void) sscanf (string, "%x", &i); 575 AppRes.field[BlankDelay2].val = i; 576 XtVaGetValues(AppRes.field[EarlySc].textwidget, 577 XtNstate, &state, NULL); 578 AppRes.field[EarlySc].val = state ? 1 : 0; 579 if (AppRes.field[InvertVclk].val != AppRes.orig[InvertVclk]) 580 printf("InvertVCLK\t\"%dx%d\" %d\n", AppRes.field[HDisplay].val, 581 AppRes.field[VDisplay].val, AppRes.field[InvertVclk].val); 582 if (AppRes.field[EarlySc].val != AppRes.orig[EarlySc]) 583 printf("EarlySC\t\t\"%dx%d\" %d\n", AppRes.field[HDisplay].val, 584 AppRes.field[VDisplay].val, AppRes.field[EarlySc].val); 585 if (AppRes.field[BlankDelay1].val != AppRes.orig[BlankDelay1] 586 || AppRes.field[BlankDelay2].val != AppRes.orig[BlankDelay2]) 587 printf("BlankDelay\t\"%dx%d\" %d %d\n", AppRes.field[HDisplay].val, 588 AppRes.field[VDisplay].val, AppRes.field[BlankDelay1].val, 589 AppRes.field[BlankDelay2].val); 590 } 591 printf("\n"); 592} 593 594static void 595AdjustCB(Widget w, XtPointer client, XtPointer call) 596{ 597 int what = (long) client; 598 Boolean state; 599 600 switch (what) { 601 case HSyncStart: 602 if (AppRes.field[HSyncEnd].val + 4 < AppRes.field[HTotal].val) { 603 AppRes.field[HSyncEnd].val += 4; 604 AppRes.field[HSyncStart].val += 4; 605 SetLabel(HSyncStart); 606 SetLabel(HSyncEnd); 607 } else 608 XBell(XtDisplay(w), 80); 609 break; 610 case -HSyncStart: 611 if (AppRes.field[HSyncStart].val - 4 > AppRes.field[HDisplay].val) { 612 AppRes.field[HSyncEnd].val -= 4; 613 AppRes.field[HSyncStart].val -= 4; 614 SetLabel(HSyncStart); 615 SetLabel(HSyncEnd); 616 } else 617 XBell(XtDisplay(w), 80); 618 break; 619 case HTotal: 620 AppRes.field[HTotal].val += 4; 621 SetLabel(HTotal); 622 UpdateSyncRates(TRUE); 623 break; 624 case -HTotal: 625 if (AppRes.field[HTotal].val - 4 > AppRes.field[HSyncEnd].val) { 626 AppRes.field[HTotal].val -= 4; 627 SetLabel(HTotal); 628 UpdateSyncRates(TRUE); 629 } else 630 XBell(XtDisplay(w), 80); 631 break; 632 case VSyncStart: 633 if (AppRes.field[VSyncEnd].val + 4 < AppRes.field[VTotal].val) { 634 AppRes.field[VSyncEnd].val += 4; 635 AppRes.field[VSyncStart].val += 4; 636 SetLabel(VSyncStart); 637 SetLabel(VSyncEnd); 638 } else 639 XBell(XtDisplay(w), 80); 640 break; 641 case -VSyncStart: 642 if (AppRes.field[VSyncStart].val - 4 > AppRes.field[VDisplay].val) { 643 AppRes.field[VSyncEnd].val -= 4; 644 AppRes.field[VSyncStart].val -= 4; 645 SetLabel(VSyncStart); 646 SetLabel(VSyncEnd); 647 } else 648 XBell(XtDisplay(w), 80); 649 break; 650 case VTotal: 651 AppRes.field[VTotal].val += 4; 652 SetLabel(VTotal); 653 UpdateSyncRates(TRUE); 654 break; 655 case -VTotal: 656 if (AppRes.field[VTotal].val - 4 > AppRes.field[VSyncEnd].val) { 657 AppRes.field[VTotal].val -= 4; 658 SetLabel(VTotal); 659 UpdateSyncRates(TRUE); 660 } else 661 XBell(XtDisplay(w), 80); 662 break; 663 } 664 SetScrollbars (); 665 XtVaGetValues(auto_apply_toggle, XtNstate, &state, NULL); 666 if (state) 667 ApplyCB (w, client, call); 668} 669 670 671#if 0 672static void 673EditCB (Widget w, XtPointer client, XtPointer call) 674{ 675 int base, current, i, len; 676 int lower, upper; 677 float percent; 678 ScrollData* sdp = (ScrollData*) client; 679 680 len = strlen (sdp->string); 681 682 for (i = 0; i < len; i++) { 683 if (!(isdigit (sdp->string[i]) || isspace (sdp->string[i]))) { 684 XBell (XtDisplay(XtParent(w)), 100); 685 return; 686 } 687 } 688 switch (sdp->me) { 689 case HSyncStart: 690 lower = atoi (AppRes.field[HDisplay].string); 691 upper = atoi (AppRes.field[HSyncEnd].string); 692 break; 693 694 case HSyncEnd: 695 lower = atoi (AppRes.field[HSyncStart].string); 696 upper = atoi (AppRes.field[HTotal].string); 697 break; 698 699 case HTotal: 700 lower = atoi (AppRes.field[HSyncEnd].string); 701 upper = atoi (AppRes.field[HDisplay].string) + 702 AppRes.field[HTotal].range; 703 break; 704 705 case VSyncStart: 706 lower = atoi (AppRes.field[VDisplay].string); 707 upper = atoi (AppRes.field[VSyncEnd].string); 708 break; 709 710 case VSyncEnd: 711 lower = atoi (AppRes.field[VSyncStart].string); 712 upper = atoi (AppRes.field[VTotal].string); 713 break; 714 715 case VTotal: 716 lower = atoi (AppRes.field[VSyncEnd].string); 717 upper = atoi (AppRes.field[VDisplay].string) + 718 AppRes.field[VTotal].range; 719 break; 720 } 721 current = atoi (sdp->string); 722 if (current < lower || current > upper) { 723 XawTextBlock text; 724 char tmp[6]; 725 726 if (current < lower) { 727 (void) sprintf (tmp, "%5d", lower); 728 current = lower; 729 } else { 730 (void) sprintf (tmp, "%5d", upper); 731 current = upper; 732 } 733 text.firstPos = 0; 734 text.length = strlen (tmp); 735 text.ptr = tmp; 736 text.format = XawFmt8Bit; 737 XawTextReplace (sdp->textwidget, 0, text.length, &text); 738 } 739 base = atoi (AppRes.field[sdp->use].string); 740 percent = ((float)(current - base)) / ((float)sdp->range); 741 XawScrollbarSetThumb (sdp->scrollwidget, percent, 0.0); 742} 743#endif 744 745static void 746FlagsEditCB (Widget w, XtPointer client, XtPointer call) 747{ 748 int i, len; 749 char* string; 750 fields findex = (fields) (unsigned long) client; 751 ScrollData* sdp = &AppRes.field[findex]; 752 753 XtVaGetValues (w, XtNstring, &string, NULL); 754 len = strlen (string); 755 if (len > 4) { 756 char buf[5]; 757 758 XBell (XtDisplay(XtParent(w)), 100); 759 (void) strncpy (buf, string, 4); 760 buf[4] = '\0'; 761 XtVaSetValues (sdp->textwidget, XtNstring, buf, NULL); 762 XawTextSetInsertionPoint (sdp->textwidget, 4); 763 } 764 765 for (i = 0; i < len; i++) { 766 if (!isxdigit (string[i])) { 767 XBell (XtDisplay(XtParent(w)), 100); 768 } 769 } 770} 771 772static void 773BlankEditCB (Widget w, XtPointer client, XtPointer call) 774{ 775 int len; 776 char* string; 777 fields findex = (fields) (unsigned long) client; 778 ScrollData* sdp = &AppRes.field[findex]; 779 char buf[2], old; 780 Boolean state; 781 Boolean noAuto = False; 782 783 XtVaGetValues (w, XtNstring, &string, NULL); 784 len = strlen (string); 785 if (len == 0) { 786 XBell (XtDisplay(XtParent(w)), 100); 787 strcpy(buf, "0"); 788 XtVaSetValues (sdp->textwidget, XtNstring, buf, NULL); 789 XawTextSetInsertionPoint (sdp->textwidget, 1); 790 return; 791 } 792 if (len > 1) { 793 if (XawTextGetInsertionPoint(sdp->textwidget) < 1) { 794 buf[0] = string[0]; 795 old = string[1]; 796 } else { 797 buf[0] = string[1]; 798 old = string[0]; 799 } 800 if (buf[0] == '+' && old < '7') 801 buf[0] = old + 1; 802 else if (buf[0] == '-' && old > '0') 803 buf[0] = old - 1; 804 if (!isdigit(buf[0]) || buf[0] > '7') { 805 XBell (XtDisplay(XtParent(w)), 100); 806 buf[0] = old; 807 if (!isdigit(buf[0]) || buf[0] > '7') 808 buf[0] = '0'; 809 noAuto = True; 810 } 811 buf[1] = '\0'; 812 XtVaSetValues (sdp->textwidget, XtNstring, buf, NULL); 813 XawTextSetInsertionPoint (sdp->textwidget, 1); 814 } 815 XtVaGetValues(auto_apply_toggle, XtNstate, &state, NULL); 816 if (state && !noAuto) 817 ApplyCB (sdp->textwidget, client, call); 818} 819 820static void 821ChangeBlankCB (Widget w, XtPointer client, XtPointer call) 822{ 823 char* string; 824 char buf[2]; 825 fields findex; 826 ScrollData* sdp; 827 Boolean state; 828 int what = (long) client; 829 830 831 if (what < 0) 832 findex = (fields)-what; 833 else 834 findex = (fields)what; 835 sdp = &AppRes.field[findex]; 836 837 XtVaGetValues (sdp->textwidget, XtNstring, &string, NULL); 838 if (what > 0) 839 string[0]++; 840 else 841 string[0]--; 842 843 if (string[0] < '0' || string[0] > '7') { 844 XBell (XtDisplay(XtParent(w)), 100); 845 return; 846 } 847 848 buf[0] = string[0]; 849 buf[1] = '\0'; 850 XtVaSetValues (sdp->textwidget, XtNstring, buf, NULL); 851 XawTextSetInsertionPoint (sdp->textwidget, 1); 852 853 XtVaGetValues(auto_apply_toggle, XtNstate, &state, NULL); 854 if (state) 855 ApplyCB (sdp->textwidget, client, call); 856} 857 858static int 859isValid(int val, int field) 860{ 861 switch(field) { 862 case HSyncStart: 863 if (val+8 > AppRes.field[HSyncEnd].val) 864 val = AppRes.field[HSyncEnd].val - 8; 865 break; 866 case HSyncEnd: 867 if (val-8 < AppRes.field[HSyncStart].val) 868 val = AppRes.field[HSyncStart].val + 8; 869 if (val > AppRes.field[HTotal].val) 870 val = AppRes.field[HTotal].val; 871 break; 872 case HTotal: 873 if (val < AppRes.field[HSyncEnd].val) 874 val = AppRes.field[HSyncEnd].val; 875 break; 876 case VSyncStart: 877 if (val+8 > AppRes.field[VSyncEnd].val) 878 val = AppRes.field[VSyncEnd].val - 8; 879 break; 880 case VSyncEnd: 881 if (val-8 < AppRes.field[VSyncStart].val) 882 val = AppRes.field[VSyncStart].val + 8; 883 if (val > AppRes.field[VTotal].val) 884 val = AppRes.field[VTotal].val; 885 break; 886 case VTotal: 887 if (val < AppRes.field[VSyncEnd].val) 888 val = AppRes.field[VSyncEnd].val; 889 break; 890 } 891 return val; 892} 893 894static void 895ScrollCB (Widget w, XtPointer client, XtPointer call) 896{ 897 float percent = *(float*) call; 898 int ipercent = percent * 100; 899 int fieldindex = (long) client; 900 ScrollData* sdp = &AppRes.field[fieldindex]; 901 902 903 904 if (ipercent != sdp->lastpercent) { 905 int tmp_val; 906 char buf[6]; 907 908 tmp_val = AppRes.field[sdp->use].val; 909 tmp_val += (int) (((float)sdp->range) * percent); 910 911 sdp->val = isValid(tmp_val, fieldindex); 912 913 sdp->lastpercent = ipercent; 914 (void) sprintf (buf, "%5d", sdp->val); 915 XtVaSetValues (sdp->textwidget, XtNlabel, buf, NULL); 916 if (sdp->val != tmp_val) { 917 int base; 918 float percent; 919 920 base = AppRes.field[sdp->use].val; 921 percent = ((float)(sdp->val - base)) / ((float)sdp->range); 922 /* This doesn't always work, why? */ 923 XawScrollbarSetThumb (sdp->scrollwidget, percent, 0.0); 924 } 925 if (fieldindex == HTotal || fieldindex == VTotal) 926 UpdateSyncRates(TRUE); 927 } 928} 929 930static void 931SwitchCB (Widget w, XtPointer client, XtPointer call) 932{ 933 XF86VidModeLockModeSwitch(XtDisplay(w), DefaultScreen (XtDisplay (w)), 934 FALSE); 935 XF86VidModeSwitchMode(XtDisplay(w), DefaultScreen (XtDisplay (w)), 936 (int)(long) client); 937 XF86VidModeLockModeSwitch(XtDisplay(w), DefaultScreen (XtDisplay (w)), 938 TRUE); 939 FetchCB(w, NULL, NULL); 940} 941 942static void 943AddCallback ( 944 Widget w, 945 String callback_name, 946 XtCallbackProc callback, 947 XtPointer client_data) 948{ 949 Widget src; 950 951 XtVaGetValues (w, XtNtextSource, &src, NULL); 952 XtAddCallback (src, callback_name, callback, client_data); 953} 954 955static void 956CreateTyp ( 957 Widget form, 958 fields findex, 959 String w1name, 960 String w2name, 961 String w3name) 962{ 963 Widget wids[3]; 964 char buf[10]; 965 966 wids[0] = XtCreateWidget (w1name, labelWidgetClass, form, NULL, 0); 967 if (findex >= PixelClock && findex <= VSyncRate) 968 (void) sprintf(buf, "%6.2f", (float)AppRes.field[findex].val / 1000.0); 969 else 970 (void) sprintf (buf, "%5d", AppRes.field[findex].val); 971 wids[1] = XtVaCreateWidget (w2name, labelWidgetClass, 972 form, XtNlabel, buf, NULL); 973 if (w3name != NULL) { 974 wids[2] = XtCreateWidget (w3name, scrollbarWidgetClass, form, NULL, 0); 975 XtAddCallback (wids[2], XtNjumpProc, ScrollCB, (XtPointer) findex); 976 XtManageChildren (wids, 3); 977 } else { 978 wids[2] = (Widget) NULL; 979 XtManageChildren (wids, 2); 980 } 981 AppRes.field[findex].textwidget = wids[1]; 982 AppRes.field[findex].scrollwidget = wids[2]; 983} 984 985 986static void 987AckWarn (Widget w, XtPointer client, XtPointer call) 988{ 989 XtPopdown((Widget) client); 990 XtDestroyWidget((Widget) client); 991} 992 993static void 994AckNoTune (Widget w, XtPointer client, XtPointer call) 995{ 996 CleanUp(XtDisplay(w)); 997#if XtSpecificationRelease < 6 998 exit (0); 999#else 1000 XtAppSetExitFlag (XtWidgetToApplicationContext (w)); 1001#endif 1002} 1003 1004static void 1005displayWarning(Widget top) 1006{ 1007 Widget w, popup, popupBox; 1008 int x, y; 1009 1010 x = DisplayWidth(XtDisplay (top),DefaultScreen (XtDisplay (top))) / 3; 1011 y = DisplayHeight(XtDisplay (top),DefaultScreen (XtDisplay (top))) / 3; 1012 1013 popup = XtVaCreatePopupShell("Warning", 1014 transientShellWidgetClass, top, 1015 XtNtitle, "WARNING", 1016 XtNx, x, 1017 XtNy, y, 1018 NULL); 1019 1020 popupBox = XtVaCreateManagedWidget( 1021 "WarningBox", 1022 boxWidgetClass, 1023 popup, 1024 NULL); 1025 1026 w = XtVaCreateManagedWidget( "WarnLabel", 1027 labelWidgetClass, 1028 popupBox, 1029 NULL); 1030 1031 w = XtVaCreateManagedWidget( "WarnOK", 1032 commandWidgetClass, 1033 popupBox, 1034 NULL); 1035 1036 XtAddCallback (w, XtNcallback, AckWarn, (XtPointer)popup); 1037 1038 w = XtVaCreateManagedWidget( "WarnCancel", 1039 commandWidgetClass, 1040 popupBox, 1041 NULL); 1042 XtAddCallback (w, XtNcallback, QuitCB, (XtPointer)NULL); 1043 1044 XtPopup(popup, XtGrabExclusive); 1045 1046} 1047 1048static void 1049displayNoTune(Widget top) 1050{ 1051 Widget w, popup, popupBox; 1052 1053 popup = XtCreateWidget ("Notice", formWidgetClass, top, NULL, 0); 1054 popupBox = XtVaCreateManagedWidget( 1055 "WarningBox", 1056 boxWidgetClass, 1057 popup, 1058 NULL); 1059 1060 w = XtVaCreateManagedWidget( "NoTuneLabel", 1061 labelWidgetClass, 1062 popupBox, 1063 NULL); 1064 1065 w = XtVaCreateManagedWidget( "NoTuneOK", 1066 commandWidgetClass, 1067 popupBox, 1068 NULL); 1069 1070 XtAddCallback (w, XtNcallback, AckNoTune, (XtPointer)popup); 1071 1072 XtManageChild (popup); 1073} 1074 1075#if 0 1076static void 1077s3Special(Widget top) 1078{ 1079 Widget w, popup, form, invert_vclk_toggle, wids[6]; 1080 char buf1[5] = {'\0',}; 1081 int x, y; 1082 1083 x = DisplayWidth(XtDisplay (top),DefaultScreen (XtDisplay (top))) / 3; 1084 y = DisplayHeight(XtDisplay (top),DefaultScreen (XtDisplay (top))) / 3; 1085 1086 popup = XtVaCreatePopupShell("S3Adjust", 1087 transientShellWidgetClass, top, 1088 XtNtitle, "S3Adjust", 1089 XtNx, x, 1090 XtNy, y, 1091 NULL); 1092 1093 form = XtVaCreateManagedWidget( 1094 "S3Box", 1095 formWidgetClass, 1096 popup, 1097 NULL); 1098 1099 w = XtVaCreateManagedWidget( "S3Title", 1100 labelWidgetClass, 1101 form, 1102 NULL); 1103 1104 invert_vclk_toggle = XtVaCreateManagedWidget( "InvertVclk-toggle", 1105 toggleWidgetClass, 1106 form, 1107 NULL); 1108 1109 wids[0] = XtCreateWidget ("Blank1-label", labelWidgetClass, 1110 form, NULL, 0); 1111 wids[1] = XtVaCreateWidget ("Blank1-text", asciiTextWidgetClass, 1112 form, XtNstring, buf1, NULL); 1113 AddCallback (wids[1], XtNcallback, FlagsEditCB, (XtPointer) NULL); 1114 1115 XtManageChildren (wids, 2); 1116 1117 XtPopup(popup, XtGrabNone); 1118 1119} 1120#endif 1121 1122 1123 1124static void 1125CreateHierarchy(Widget top) 1126{ 1127 char buf[5]; 1128 Widget form, forms[14], s3form; 1129 Widget wids[10]; 1130 Widget boxW, popdownW, w; 1131 int i; 1132 int x, y; 1133 static String form_names[] = { 1134 "HDisplay-form", 1135 "HSyncStart-form", 1136 "HSyncEnd-form", 1137 "HTotal-form", 1138 "VDisplay-form", 1139 "VSyncStart-form", 1140 "VSyncEnd-form", 1141 "VTotal-form", 1142 "Flags-form", 1143 "Buttons-form", 1144 "PixelClock-form", 1145 "HSyncRate-form", 1146 "VSyncRate-form", 1147 "Buttons2-form", 1148 }; 1149 1150 form = XtCreateWidget ("form", formWidgetClass, top, NULL, 0); 1151 for (i = 0; i < 14; i++) 1152 forms[i] = XtCreateWidget (form_names[i], formWidgetClass, 1153 form, NULL, 0); 1154 1155 CreateTyp (forms[0], HDisplay, "HDisplay-label", "HDisplay-text", NULL); 1156 CreateTyp (forms[1], HSyncStart, "HSyncStart-label", 1157 "HSyncStart-text", "HSyncStart-scrollbar"); 1158 CreateTyp (forms[2], HSyncEnd, "HSyncEnd-label", "HSyncEnd-text", 1159 "HSyncEnd-scrollbar"); 1160 CreateTyp (forms[3], HTotal, "HTotal-label", "HTotal-text", 1161 "HTotal-scrollbar"); 1162 1163 w = XtVaCreateManagedWidget( 1164 "Left-button", 1165 commandWidgetClass, 1166 forms[3], 1167 NULL); 1168 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)HSyncStart); 1169 w = XtVaCreateManagedWidget( 1170 "Right-button", 1171 commandWidgetClass, 1172 forms[3], 1173 NULL); 1174 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)-HSyncStart); 1175 w= XtVaCreateManagedWidget( 1176 "Wider-button", 1177 commandWidgetClass, 1178 forms[3], 1179 NULL); 1180 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)-HTotal); 1181 w = XtVaCreateManagedWidget( 1182 "Narrower-button", 1183 commandWidgetClass, 1184 forms[3], 1185 NULL); 1186 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)HTotal); 1187 CreateTyp (forms[4], VDisplay, "VDisplay-label", "VDisplay-text", NULL); 1188 CreateTyp (forms[5], VSyncStart, "VSyncStart-label", 1189 "VSyncStart-text", "VSyncStart-scrollbar"); 1190 CreateTyp (forms[6], VSyncEnd, "VSyncEnd-label", "VSyncEnd-text", 1191 "VSyncEnd-scrollbar"); 1192 CreateTyp (forms[7], VTotal, "VTotal-label", "VTotal-text", 1193 "VTotal-scrollbar"); 1194 w = XtVaCreateManagedWidget( 1195 "Up-button", 1196 commandWidgetClass, 1197 forms[7], 1198 NULL); 1199 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)VSyncStart); 1200 w = XtVaCreateManagedWidget( 1201 "Down-button", 1202 commandWidgetClass, 1203 forms[7], 1204 NULL); 1205 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)-VSyncStart); 1206 w= XtVaCreateManagedWidget( 1207 "Shorter-button", 1208 commandWidgetClass, 1209 forms[7], 1210 NULL); 1211 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)VTotal); 1212 w = XtVaCreateManagedWidget( 1213 "Taller-button", 1214 commandWidgetClass, 1215 forms[7], 1216 NULL); 1217 XtAddCallback (w, XtNcallback, AdjustCB, (XtPointer)-VTotal); 1218 1219 (void) sprintf (buf, "%04x", AppRes.field[Flags].val); 1220 wids[0] = XtCreateWidget ("Flags-label", labelWidgetClass, 1221 forms[8], NULL, 0); 1222 wids[1] = XtVaCreateWidget ("Flags-text", asciiTextWidgetClass, 1223 forms[8], XtNstring, buf, XtNtranslations, trans, NULL); 1224 AddCallback (wids[1], XtNcallback, FlagsEditCB, (XtPointer) Flags); 1225 XtManageChildren (wids, 2); 1226 AppRes.field[Flags].textwidget = wids[1]; 1227 1228 wids[0] = XtCreateWidget ("Quit-button", commandWidgetClass, 1229 forms[9], NULL, 0); 1230 XtAddCallback (wids[0], XtNcallback, QuitCB, NULL); 1231 1232 wids[1] = XtCreateWidget ("Apply-button", commandWidgetClass, 1233 forms[9], NULL, 0); 1234 XtAddCallback (wids[1], XtNcallback, ApplyCB, NULL); 1235 1236 wids[2] = XtCreateWidget ("AutoApply-toggle", toggleWidgetClass, 1237 forms[9], NULL, 0); 1238 auto_apply_toggle = wids[2]; 1239 1240 wids[3] = XtCreateWidget ("Test-button", commandWidgetClass, 1241 forms[9], NULL, 0); 1242 XtAddCallback (wids[3], XtNcallback, TestCB, NULL); 1243 1244 wids[4] = XtCreateWidget ("Restore-button", commandWidgetClass, 1245 forms[9], NULL, 0); 1246 XtAddCallback (wids[4], XtNcallback, RestoreCB, NULL); 1247 1248 XtManageChildren (wids, 5); 1249 1250 1251 CreateTyp (forms[10], PixelClock, "PixelClock-label", "PixelClock-text", 1252 NULL); 1253 CreateTyp (forms[11], HSyncRate, "HSyncRate-label", "HSyncRate-text", 1254 NULL); 1255 CreateTyp (forms[12], VSyncRate, "VSyncRate-label", "VSyncRate-text", 1256 NULL); 1257 1258 wids[0] = XtCreateWidget ("Fetch-button", commandWidgetClass, 1259 forms[13], NULL, 0); 1260 XtAddCallback (wids[0], XtNcallback, FetchCB, NULL); 1261 1262 wids[1] = XtCreateWidget ("Show-button", commandWidgetClass, 1263 forms[13], NULL, 0); 1264 XtAddCallback (wids[1], XtNcallback, ShowCB, NULL); 1265 1266 wids[2] = XtCreateWidget ("Next-button", commandWidgetClass, 1267 forms[13], NULL, 0); 1268 XtAddCallback (wids[2], XtNcallback, SwitchCB, (XtPointer)1); 1269 1270 wids[3] = XtCreateWidget ("Prev-button", commandWidgetClass, 1271 forms[13], NULL, 0); 1272 XtAddCallback (wids[3], XtNcallback, SwitchCB, (XtPointer)-1); 1273 1274 XtManageChildren (wids, 4); 1275 1276 XtManageChildren (forms, 14); 1277 1278 if (S3Specials) { 1279 char buf[2] = "0"; 1280 s3form = XtCreateWidget ("S3-form", formWidgetClass, 1281 form, NULL, 0); 1282 wids[0] = XtVaCreateWidget("InvertVclk-toggle", toggleWidgetClass, 1283 s3form, XtNstate, AppRes.field[InvertVclk].val, NULL); 1284 XtAddCallback (wids[0], XtNcallback, ApplyIfAutoCB, NULL); 1285 AppRes.field[InvertVclk].textwidget = wids[0]; 1286 wids[1] = XtVaCreateWidget("EarlySc-toggle", toggleWidgetClass, 1287 s3form, XtNstate, AppRes.field[EarlySc].val, NULL); 1288 XtAddCallback (wids[1], XtNcallback, ApplyIfAutoCB, NULL); 1289 AppRes.field[EarlySc].textwidget = wids[1]; 1290 wids[2] = XtCreateWidget("Blank1-label", labelWidgetClass, s3form, 1291 NULL, 0); 1292 wids[3] = XtVaCreateWidget("Blank1Dec-button", commandWidgetClass, 1293 s3form, NULL); 1294 XtAddCallback (wids[3], XtNcallback, ChangeBlankCB, 1295 (XtPointer)-BlankDelay1); 1296 (void) sprintf (buf, "%d", AppRes.field[BlankDelay1].val); 1297 wids[4] = XtVaCreateWidget("Blank1-text", asciiTextWidgetClass, 1298 s3form, XtNstring, buf, XtNtranslations, trans, NULL); 1299 AddCallback(wids[4], XtNcallback, BlankEditCB, (XPointer) BlankDelay1); 1300 AppRes.field[BlankDelay1].textwidget = wids[4]; 1301 wids[5] = XtVaCreateWidget("Blank1Inc-button", commandWidgetClass, 1302 s3form, NULL); 1303 XtAddCallback (wids[5], XtNcallback, ChangeBlankCB, 1304 (XtPointer)BlankDelay1); 1305 1306 wids[6] = XtCreateWidget("Blank2-label", labelWidgetClass, s3form, 1307 NULL, 0); 1308 wids[7] = XtVaCreateWidget("Blank2Dec-button", commandWidgetClass, 1309 s3form, NULL); 1310 XtAddCallback (wids[7], XtNcallback, ChangeBlankCB, 1311 (XtPointer)-BlankDelay2); 1312 (void) sprintf (buf, "%d", AppRes.field[BlankDelay2].val); 1313 wids[8] = XtVaCreateWidget("Blank2-text", asciiTextWidgetClass, 1314 s3form, XtNstring, buf, XtNtranslations, trans, NULL); 1315 AddCallback(wids[8], XtNcallback, BlankEditCB, (XPointer) BlankDelay2); 1316 AppRes.field[BlankDelay2].textwidget = wids[8]; 1317 wids[9] = XtVaCreateWidget("Blank2Inc-button", commandWidgetClass, 1318 s3form, NULL); 1319 XtAddCallback (wids[9], XtNcallback, ChangeBlankCB, 1320 (XtPointer)BlankDelay2); 1321 XtManageChildren (wids, 10); 1322 XtManageChild(s3form); 1323 } 1324 1325 XtManageChild (form); 1326 1327 SetScrollbars (); 1328 x = DisplayWidth(XtDisplay (top),DefaultScreen (XtDisplay (top))) / 2; 1329 y = DisplayHeight(XtDisplay (top),DefaultScreen (XtDisplay (top))) / 2; 1330 1331 invalid_mode_popup = XtVaCreatePopupShell("invalidMode", 1332 transientShellWidgetClass, top, 1333 XtNtitle, "Invalid Mode requested", 1334 XtNx, x - 20, 1335 XtNy, y - 40, 1336 NULL); 1337 1338 testing_popup = XtVaCreatePopupShell("testing", 1339 transientShellWidgetClass, top, 1340 XtNtitle, "Testing_1_2_3", 1341 XtNx, x - 20, 1342 XtNy, y - 40, 1343 NULL); 1344 boxW = XtVaCreateManagedWidget( 1345 "TestingBox", 1346 boxWidgetClass, 1347 testing_popup, 1348 NULL); 1349 1350 w = XtVaCreateManagedWidget( 1351 "testingMessage", 1352 labelWidgetClass, 1353 boxW, 1354 NULL); 1355 1356 w = XtVaCreateManagedWidget( 1357 "Abort", 1358 commandWidgetClass, 1359 boxW, 1360 NULL); 1361 1362 XtAddCallback (w, XtNcallback, (XtCallbackProc) TestTOCB, 1363 (XtPointer) NULL); 1364 1365 boxW = XtVaCreateManagedWidget( 1366 "invalidBox", 1367 boxWidgetClass, 1368 invalid_mode_popup, 1369 NULL); 1370 1371 (void) XtVaCreateManagedWidget( 1372 "ErrorMessage", 1373 labelWidgetClass, 1374 boxW, 1375 NULL); 1376 1377 popdownW = XtVaCreateManagedWidget( 1378 "AckError", 1379 commandWidgetClass, 1380 boxW, 1381 NULL); 1382 1383 XtAddCallback (popdownW, XtNcallback, (XtCallbackProc)popdownInvalid, 1384 (XtPointer) invalid_mode_popup); 1385} 1386 1387static void 1388QuitAction (Widget w, XEvent* e, String* vector, Cardinal* count) 1389{ 1390 if ((e->type == ClientMessage 1391 && e->xclient.data.l[0] == (long) wm_delete_window) 1392 || e->type == KeyPress) 1393 QuitCB(w, NULL, NULL); 1394} 1395 1396static void 1397RestoreAction (Widget w, XEvent* e, String* vector, Cardinal* count) 1398{ 1399 Boolean state; 1400 1401 RestoreCB(w, NULL, NULL); 1402 XtVaGetValues(auto_apply_toggle, XtNstate, &state, NULL); 1403 if (!state) 1404 ApplyCB (w, NULL, NULL); 1405} 1406 1407 1408static void 1409ShowAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1410{ 1411 ShowCB(w, NULL, NULL); 1412} 1413 1414static void 1415MoveLeftAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1416{ 1417 AdjustCB(w, (XtPointer)HSyncStart, NULL); 1418} 1419 1420static void 1421MoveRightAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1422{ 1423 AdjustCB(w, (XtPointer)-HSyncStart, NULL); 1424} 1425 1426static void 1427NarrowerAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1428{ 1429 AdjustCB(w, (XtPointer)HTotal, NULL); 1430} 1431 1432static void 1433WiderAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1434{ 1435 AdjustCB(w, (XtPointer)-HTotal, NULL); 1436} 1437 1438static void 1439MoveUpAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1440{ 1441 AdjustCB(w, (XtPointer)VSyncStart, NULL); 1442} 1443 1444static void 1445MoveDownAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1446{ 1447 AdjustCB(w, (XtPointer)-VSyncStart, NULL); 1448} 1449 1450static void 1451TallerAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1452{ 1453 AdjustCB(w, (XtPointer)-VTotal, NULL); 1454} 1455 1456static void 1457ShorterAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1458{ 1459 AdjustCB(w, (XtPointer)VTotal, NULL); 1460} 1461 1462static void 1463NextModeAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1464{ 1465 SwitchCB(w, (XPointer) 1, NULL); 1466} 1467 1468static void 1469PrevModeAction(Widget w, XEvent* e, String* vector, Cardinal* count) 1470{ 1471 SwitchCB(w, (XPointer) -1, NULL); 1472} 1473 1474 1475 1476static void 1477usage(void) 1478{ 1479 fprintf(stderr, "Usage: xvidtune [option]\n"); 1480 fprintf(stderr, " where option is one of:\n"); 1481 fprintf(stderr, " -show Print current modeline to stdout\n"); 1482 fprintf(stderr, " -next Switch to next video mode\n"); 1483 fprintf(stderr, " -prev Switch to previous video mode\n"); 1484 fprintf(stderr, " -unlock Enable mode switch hot-keys\n"); 1485 fprintf(stderr, " -timeout [seconds] Set testmode timeout in seconds,\n"); 1486 exit(1); 1487} 1488 1489 1490int 1491main (int argc, char** argv) 1492{ 1493 Widget top; 1494 XtAppContext app; 1495 Display* dpy; 1496 Bool modeSettable = TRUE; 1497 1498 static XtActionsRec actions[] = { { "xvidtune-quit", QuitAction }, 1499 { "xvidtune-restore", RestoreAction }, 1500 { "xvidtune-show", ShowAction }, 1501 { "xvidtune-moveleft", MoveLeftAction }, 1502 { "xvidtune-moveright", MoveRightAction }, 1503 { "xvidtune-wider", WiderAction }, 1504 { "xvidtune-narrower", NarrowerAction }, 1505 { "xvidtune-moveup", MoveUpAction }, 1506 { "xvidtune-movedown", MoveDownAction }, 1507 { "xvidtune-taller", TallerAction }, 1508 { "xvidtune-shorter", ShorterAction }, 1509 { "xvidtune-nextmode", NextModeAction }, 1510 { "xvidtune-prevmode", PrevModeAction } }; 1511 1512 Top = top = XtVaOpenApplication (&app, "Xvidtune", NULL, 0, &argc, argv, 1513 NULL, applicationShellWidgetClass, 1514 XtNmappedWhenManaged, False, NULL); 1515 1516 XtGetApplicationResources (top, (XtPointer)&AppRes, 1517 Resources, XtNumber(Resources), 1518 NULL, 0); 1519 1520 if (!AppRes.ad_installed) { 1521 fprintf(stderr, "Please install the program before using\n"); 1522 return 3; 1523 } 1524 1525 if (!XF86VidModeQueryVersion(XtDisplay (top), &MajorVersion, &MinorVersion)) { 1526 fprintf(stderr, "Unable to query video extension version\n"); 1527 return 2; 1528 } 1529 1530 if (!XF86VidModeQueryExtension(XtDisplay (top), &EventBase, &ErrorBase)) { 1531 fprintf(stderr, "Unable to query video extension information\n"); 1532 return 2; 1533 } 1534 1535 /* Fail if the extension version in the server is too old */ 1536 if (MajorVersion < MINMAJOR || 1537 (MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) { 1538 fprintf(stderr, 1539 "Xserver is running an old XFree86-VidModeExtension version" 1540 " (%d.%d)\n", MajorVersion, MinorVersion); 1541 fprintf(stderr, "Minimum required version is %d.%d\n", 1542 MINMAJOR, MINMINOR); 1543 exit(2); 1544 } 1545 1546 /* This should probably be done differently */ 1547 1548 if( argc == 3 ) { /* this can only be the timeout case */ 1549 if( (!strcmp(argv[1], "-timeout")) ) { 1550 TestTimeout = ((unsigned long) atol( argv[2] )) * 1000L; 1551 } 1552 else 1553 usage(); 1554 } 1555 1556 if (argc > 1) { 1557 int i = 0; 1558 1559 if (argc != 2) 1560 usage(); 1561 if (!strcmp(argv[1], "-show")) { 1562 if (!GetModeLine(XtDisplay (top), DefaultScreen (XtDisplay (top)))) { 1563 fprintf(stderr, "Unable to get mode info\n"); 1564 CleanUp(XtDisplay (top)); 1565 return 2; 1566 } 1567 ShowCB(top, NULL, NULL); 1568 return 0; 1569 } else if (!strcmp(argv[1], "-next")) 1570 i = 1; 1571 else if (!strcmp(argv[1], "-prev")) 1572 i = -1; 1573 else if (!strcmp(argv[1], "-unlock")) { 1574 CleanUp(XtDisplay (top)); 1575 XSync(XtDisplay (top), True); 1576 return 0; 1577 } else 1578 usage(); 1579 if (i != 0) { 1580 XF86VidModeSwitchMode(XtDisplay (top), 1581 DefaultScreen (XtDisplay (top)), i); 1582 XSync(XtDisplay (top), True); 1583 return 0; 1584 } 1585 } 1586 if (!GetMonitor(XtDisplay (top), DefaultScreen (XtDisplay (top)))) { 1587 fprintf(stderr, "Unable to query monitor info\n"); 1588 return 2; 1589 } 1590 1591 if (!XF86VidModeLockModeSwitch(XtDisplay (top), 1592 DefaultScreen (XtDisplay (top)), TRUE)) { 1593 fprintf(stderr, "Failed to disable mode-switch hot-keys\n"); 1594 return 2; 1595 } 1596 1597 signal(SIGINT, CatchSig); 1598 signal(SIGQUIT, CatchSig); 1599 signal(SIGTERM, CatchSig); 1600 signal(SIGHUP, CatchSig); 1601 sigId = XtAppAddSignal(app, CatchXtSig, NULL); 1602 1603 if (!GetModeLine(XtDisplay (top), DefaultScreen (XtDisplay (top)))) { 1604 fprintf(stderr, "Unable to get mode info\n"); 1605 CleanUp(XtDisplay (top)); 1606 return 2; 1607 } 1608 1609 xtErrorfunc = XSetErrorHandler(vidmodeError); 1610 1611 trans = XtParseTranslationTable ("\ 1612 <Key>0: insert-char()\n<Key>1: insert-char()\n\ 1613 <Key>2: insert-char()\n<Key>3: insert-char()\n\ 1614 <Key>4: insert-char()\n<Key>5: insert-char()\n\ 1615 <Key>6: insert-char()\n<Key>7: insert-char()\n\ 1616 <Key>8: insert-char()\n<Key>9: insert-char()\n\ 1617 <Key>a: insert-char()\n<Key>b: insert-char()\n\ 1618 <Key>c: insert-char()\n<Key>d: insert-char()\n\ 1619 <Key>e: insert-char()\n<Key>f: insert-char()\n\ 1620 <Key>+: insert-char()\n<Key>-: insert-char()\n\ 1621 <Key>r: xvidtune-restore()\n<Key>q: xvidtune-quit()\n\ 1622 <Key>BackSpace: delete-previous-character()\n\ 1623 <Key>Right: forward-character()\n<Key>KP_Right: forward-character()\n\ 1624 <Key>Left: backward-character()\n<Key>KP_Left: backward-character()\n\ 1625 <Key>Delete: delete-previous-character()\n\ 1626 <Key>KP_Delete: delete-previous-character()\n\ 1627 <EnterWindow>: enter-window()\n<LeaveWindow>: leave-window()\n\ 1628 <FocusIn>: focus-in()\n<FocusOut>: focus-out()\n\ 1629 <Btn1Down>: select-start()\n"); 1630 1631 if (!ModeSettable()) { 1632 printf("Video are not settable on this chip\n"); 1633 displayNoTune(top); 1634 modeSettable = FALSE; 1635 } else 1636 CreateHierarchy (top); 1637 1638 1639 XtAppAddActions (app, actions, XtNumber(actions)); 1640 1641 XtOverrideTranslations (top, 1642 XtParseTranslationTable ("<Message>WM_PROTOCOLS: xvidtune-quit()")); 1643 1644 XtRealizeWidget (top); 1645 1646 dpy = XtDisplay(top); 1647 1648 wm_delete_window = XInternAtom (dpy, "WM_DELETE_WINDOW", False); 1649 1650 (void) XSetWMProtocols (dpy, XtWindow (top), &wm_delete_window, 1); 1651 1652 XtMapWidget (top); 1653 1654 if (modeSettable) 1655 displayWarning(top); 1656 1657 /* really we should run our own event dispatching here until the 1658 * warning has been read... 1659 */ 1660 XtAppMainLoop (app); 1661 1662 return 0; 1663} 1664