1/* 2 *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. 3 * 4 *Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 *"Software"), to deal in the Software without restriction, including 7 *without limitation the rights to use, copy, modify, merge, publish, 8 *distribute, sublicense, and/or sell copies of the Software, and to 9 *permit persons to whom the Software is furnished to do so, subject to 10 *the following conditions: 11 * 12 *The above copyright notice and this permission notice shall be 13 *included in all copies or substantial portions of the Software. 14 * 15 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR 19 *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 * 23 *Except as contained in this notice, the name of Harold L Hunt II 24 *shall not be used in advertising or otherwise to promote the sale, use 25 *or other dealings in this Software without prior written authorization 26 *from Harold L Hunt II. 27 * 28 * Authors: Harold L Hunt II 29 * Earle F. Philhower III 30 */ 31 32#ifdef HAVE_XWIN_CONFIG_H 33#include <xwin-config.h> 34#endif 35#include "win.h" 36#ifdef __CYGWIN__ 37#include <sys/cygwin.h> 38#endif 39#include <shellapi.h> 40#include "winprefs.h" 41 42 43/* 44 * References to external globals 45 */ 46 47#ifdef XWIN_CLIPBOARD 48extern Bool g_fClipboardStarted; 49#endif 50/* 51 * Local function prototypes 52 */ 53 54static wBOOL CALLBACK 55winExitDlgProc (HWND hDialog, UINT message, 56 WPARAM wParam, LPARAM lParam); 57 58static wBOOL CALLBACK 59winChangeDepthDlgProc (HWND hDialog, UINT message, 60 WPARAM wParam, LPARAM lParam); 61 62static wBOOL CALLBACK 63winAboutDlgProc (HWND hDialog, UINT message, 64 WPARAM wParam, LPARAM lParam); 65 66 67static void 68winDrawURLWindow (LPARAM lParam); 69 70static LRESULT CALLBACK 71winURLWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); 72 73static void 74winOverrideURLButton (HWND hdlg, int id); 75 76static void 77winUnoverrideURLButton (HWND hdlg, int id); 78 79 80/* 81 * Owner-draw a button as a URL 82 */ 83 84static void 85winDrawURLWindow (LPARAM lParam) 86{ 87 DRAWITEMSTRUCT *draw; 88 char str[256]; 89 RECT rect; 90 HFONT font; 91 COLORREF crText; 92 93 draw = (DRAWITEMSTRUCT *) lParam; 94 GetWindowText (draw->hwndItem, str, sizeof(str)); 95 str[255] = 0; 96 GetClientRect (draw->hwndItem, &rect); 97 98 /* Color the button depending upon its state */ 99 if (draw->itemState & ODS_SELECTED) 100 crText = RGB(128+64,0,0); 101 else if (draw->itemState & ODS_FOCUS) 102 crText = RGB(0,128+64,0); 103 else 104 crText = RGB(0,0,128+64); 105 SetTextColor (draw->hDC, crText); 106 107 /* Create font 8 high, standard dialog font */ 108 font = CreateFont (-8, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, 109 0, 0, 0, 0, 0, "MS Sans Serif"); 110 if (!font) 111 { 112 ErrorF ("winDrawURLWindow: Unable to create URL font, bailing.\n"); 113 return; 114 } 115 /* Draw it */ 116 SetBkMode (draw->hDC, OPAQUE); 117 SelectObject (draw->hDC, font); 118 DrawText (draw->hDC, str, strlen (str),&rect,DT_CENTER | DT_VCENTER); 119 /* Delete the created font, replace it with stock font */ 120 DeleteObject (SelectObject (draw->hDC, GetStockObject (ANSI_VAR_FONT))); 121} 122 123 124/* 125 * WndProc for overridden buttons 126 */ 127 128static LRESULT CALLBACK 129winURLWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 130{ 131 WNDPROC origCB = NULL; 132 HCURSOR cursor; 133 134 /* If it's a SetCursor message, tell it to the hand */ 135 if (msg==WM_SETCURSOR) { 136 cursor = LoadCursor (NULL, IDC_HAND); 137 if (cursor) 138 SetCursor (cursor); 139 return TRUE; 140 } 141 origCB = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA); 142 /* Otherwise fall through to original WndProc */ 143 if (origCB) 144 return CallWindowProc (origCB, hwnd, msg, wParam, lParam); 145 else 146 return FALSE; 147} 148 149 150/* 151 * Register and unregister the custom WndProc 152 */ 153 154static void 155winOverrideURLButton (HWND hwnd, int id) 156{ 157 WNDPROC origCB; 158 origCB = (WNDPROC)SetWindowLongPtr(GetDlgItem (hwnd, id), 159 GWLP_WNDPROC, (LONG_PTR)winURLWndProc); 160 SetWindowLongPtr(GetDlgItem (hwnd, id), GWLP_USERDATA, (LONG_PTR)origCB); 161} 162 163static void 164winUnoverrideURLButton (HWND hwnd, int id) 165{ 166 WNDPROC origCB; 167 origCB = (WNDPROC)SetWindowLongPtr(GetDlgItem (hwnd, id), 168 GWLP_USERDATA, 0); 169 if (origCB) 170 SetWindowLongPtr(GetDlgItem (hwnd, id), GWLP_WNDPROC, (LONG_PTR)origCB); 171} 172 173 174/* 175 * Center a dialog window in the desktop window 176 * and set small and large icons to X icons. 177 */ 178 179static void 180winInitDialog (HWND hwndDlg) 181{ 182 HWND hwndDesk; 183 RECT rc, rcDlg, rcDesk; 184 HICON hIcon, hIconSmall; 185 186 hwndDesk = GetParent (hwndDlg); 187 if (!hwndDesk || IsIconic (hwndDesk)) 188 hwndDesk = GetDesktopWindow (); 189 190 /* Remove minimize and maximize buttons */ 191 SetWindowLongPtr(hwndDlg, GWL_STYLE, 192 GetWindowLongPtr(hwndDlg, GWL_STYLE) 193 & ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX)); 194 195 /* Set Window not to show in the task bar */ 196 SetWindowLongPtr(hwndDlg, GWL_EXSTYLE, 197 GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_APPWINDOW ); 198 199 /* Center dialog window in the screen. Not done for multi-monitor systems, where 200 * it is likely to end up split across the screens. In that case, it appears 201 * near the Tray icon. 202 */ 203 if (GetSystemMetrics(SM_CMONITORS)>1) { 204 /* Still need to refresh the frame change. */ 205 SetWindowPos (hwndDlg, HWND_TOPMOST, 0,0,0,0, 206 SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); 207 } else { 208 GetWindowRect (hwndDesk, &rcDesk); 209 GetWindowRect (hwndDlg, &rcDlg); 210 CopyRect (&rc, &rcDesk); 211 212 OffsetRect (&rcDlg, -rcDlg.left, -rcDlg.top); 213 OffsetRect (&rc, -rc.left, -rc.top); 214 OffsetRect (&rc, -rcDlg.right, -rcDlg.bottom); 215 216 SetWindowPos (hwndDlg, 217 HWND_TOPMOST, 218 rcDesk.left + (rc.right / 2), 219 rcDesk.top + (rc.bottom / 2), 220 0, 0, 221 SWP_NOSIZE | SWP_FRAMECHANGED); 222 } 223 224#ifdef XWIN_MULTIWINDOW 225 if (g_hIconX) hIcon=g_hIconX; 226 else 227#endif 228 hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)); 229 230#ifdef XWIN_MULTIWINDOW 231 if (g_hSmallIconX) hIconSmall=g_hSmallIconX; 232 else 233#endif 234 hIconSmall = LoadImage (g_hInstance, 235 MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON, 236 GetSystemMetrics(SM_CXSMICON), 237 GetSystemMetrics(SM_CYSMICON), 238 LR_SHARED); 239 240 PostMessage (hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) hIcon); 241 PostMessage (hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall); 242} 243 244 245/* 246 * Display the Exit dialog box 247 */ 248 249void 250winDisplayExitDialog (winPrivScreenPtr pScreenPriv) 251{ 252 int i; 253 int liveClients = 0; 254 255 /* Count up running clients (clients[0] is serverClient) */ 256 for (i = 1; i < currentMaxClients; i++) 257 if (clients[i] != NullClient) 258 liveClients++; 259#if defined(XWIN_MULTIWINDOW) 260 /* Count down server internal clients */ 261 if (pScreenPriv->pScreenInfo->fMultiWindow) 262 liveClients -= 2; /* multiwindow window manager & XMsgProc */ 263#endif 264#if defined(XWIN_CLIPBOARD) 265 if (g_fClipboardStarted) 266 liveClients--; /* clipboard manager */ 267#endif 268 269 /* A user reported that this sometimes drops below zero. just eye-candy. */ 270 if (liveClients < 0) 271 liveClients = 0; 272 273 /* Don't show the exit confirmation dialog if SilentExit & no clients, 274 or ForceExit, is enabled */ 275 if ((pref.fSilentExit && liveClients <= 0) || pref.fForceExit) 276 { 277 if (g_hDlgExit != NULL) 278 { 279 DestroyWindow (g_hDlgExit); 280 g_hDlgExit = NULL; 281 } 282 PostMessage (pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0); 283 return; 284 } 285 286 pScreenPriv->iConnectedClients = liveClients; 287 288 /* Check if dialog already exists */ 289 if (g_hDlgExit != NULL) 290 { 291 /* Dialog box already exists, display it */ 292 ShowWindow (g_hDlgExit, SW_SHOWDEFAULT); 293 294 /* User has lost the dialog. Show them where it is. */ 295 SetForegroundWindow (g_hDlgExit); 296 297 return; 298 } 299 300 /* Create dialog box */ 301 g_hDlgExit = CreateDialogParam (g_hInstance, 302 "EXIT_DIALOG", 303 pScreenPriv->hwndScreen, 304 winExitDlgProc, 305 (int) pScreenPriv); 306 307 /* Show the dialog box */ 308 ShowWindow (g_hDlgExit, SW_SHOW); 309 310 /* Needed to get keyboard controls (tab, arrows, enter, esc) to work */ 311 SetForegroundWindow (g_hDlgExit); 312 313 /* Set focus to the Cancel button */ 314 PostMessage (g_hDlgExit, WM_NEXTDLGCTL, 315 (WPARAM)GetDlgItem (g_hDlgExit, IDCANCEL), TRUE); 316} 317 318#define CONNECTED_CLIENTS_FORMAT "There %s currently %d client%s connected." 319 320 321/* 322 * Exit dialog window procedure 323 */ 324 325static wBOOL CALLBACK 326winExitDlgProc (HWND hDialog, UINT message, 327 WPARAM wParam, LPARAM lParam) 328{ 329 static winPrivScreenPtr s_pScreenPriv = NULL; 330 331 /* Branch on message type */ 332 switch (message) 333 { 334 case WM_INITDIALOG: 335 { 336 char *pszConnectedClients; 337 338 /* Store pointers to private structures for future use */ 339 s_pScreenPriv = (winPrivScreenPtr) lParam; 340 341 winInitDialog (hDialog); 342 343 /* Format the connected clients string */ 344 if (asprintf (&pszConnectedClients, CONNECTED_CLIENTS_FORMAT, 345 (s_pScreenPriv->iConnectedClients == 1) ? "is" : "are", 346 s_pScreenPriv->iConnectedClients, 347 (s_pScreenPriv->iConnectedClients == 1) ? "" : "s") == -1) 348 return TRUE; 349 350 351 352 /* Set the number of connected clients */ 353 SetWindowText (GetDlgItem (hDialog, IDC_CLIENTS_CONNECTED), 354 pszConnectedClients); 355 free(pszConnectedClients); 356 } 357 return TRUE; 358 359 case WM_COMMAND: 360 switch (LOWORD (wParam)) 361 { 362 case IDOK: 363 /* Send message to call the GiveUp function */ 364 PostMessage (s_pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0); 365 DestroyWindow (g_hDlgExit); 366 g_hDlgExit = NULL; 367 368 /* Fix to make sure keyboard focus isn't trapped */ 369 PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); 370 return TRUE; 371 372 case IDCANCEL: 373 DestroyWindow (g_hDlgExit); 374 g_hDlgExit = NULL; 375 376 /* Fix to make sure keyboard focus isn't trapped */ 377 PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); 378 return TRUE; 379 } 380 break; 381 382 case WM_MOUSEMOVE: 383 case WM_NCMOUSEMOVE: 384 /* Show the cursor if it is hidden */ 385 if (g_fSoftwareCursor && !g_fCursor) 386 { 387 g_fCursor = TRUE; 388 ShowCursor (TRUE); 389 } 390 return TRUE; 391 392 case WM_CLOSE: 393 DestroyWindow (g_hDlgExit); 394 g_hDlgExit = NULL; 395 396 /* Fix to make sure keyboard focus isn't trapped */ 397 PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); 398 return TRUE; 399 } 400 401 return FALSE; 402} 403 404 405/* 406 * Display the Depth Change dialog box 407 */ 408 409void 410winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv) 411{ 412 /* Check if dialog already exists */ 413 if (g_hDlgDepthChange != NULL) 414 { 415 /* Dialog box already exists, display it */ 416 ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT); 417 418 /* User has lost the dialog. Show them where it is. */ 419 SetForegroundWindow (g_hDlgDepthChange); 420 421 return; 422 } 423 424 /* 425 * Display a notification to the user that the visual 426 * will not be displayed until the Windows display depth 427 * is restored to the original value. 428 */ 429 g_hDlgDepthChange = CreateDialogParam (g_hInstance, 430 "DEPTH_CHANGE_BOX", 431 pScreenPriv->hwndScreen, 432 winChangeDepthDlgProc, 433 (int) pScreenPriv); 434 /* Show the dialog box */ 435 ShowWindow (g_hDlgDepthChange, SW_SHOW); 436 437 ErrorF ("winDisplayDepthChangeDialog - DialogBox returned: %d\n", 438 (int) g_hDlgDepthChange); 439 ErrorF ("winDisplayDepthChangeDialog - GetLastError: %d\n", 440 (int) GetLastError ()); 441 442 /* Minimize the display window */ 443 ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE); 444} 445 446 447/* 448 * Process messages for the dialog that is displayed for 449 * disruptive screen depth changes. 450 */ 451 452static wBOOL CALLBACK 453winChangeDepthDlgProc (HWND hwndDialog, UINT message, 454 WPARAM wParam, LPARAM lParam) 455{ 456 static winPrivScreenPtr s_pScreenPriv = NULL; 457 static winScreenInfo *s_pScreenInfo = NULL; 458 static ScreenPtr s_pScreen = NULL; 459 460#if CYGDEBUG 461 winDebug ("winChangeDepthDlgProc\n"); 462#endif 463 464 /* Branch on message type */ 465 switch (message) 466 { 467 case WM_INITDIALOG: 468#if CYGDEBUG 469 winDebug ("winChangeDepthDlgProc - WM_INITDIALOG\n"); 470#endif 471 472 /* Store pointers to private structures for future use */ 473 s_pScreenPriv = (winPrivScreenPtr) lParam; 474 s_pScreenInfo = s_pScreenPriv->pScreenInfo; 475 s_pScreen = s_pScreenInfo->pScreen; 476 477#if CYGDEBUG 478 winDebug ("winChangeDepthDlgProc - WM_INITDIALOG - s_pScreenPriv: %08x, " 479 "s_pScreenInfo: %08x, s_pScreen: %08x\n", 480 s_pScreenPriv, s_pScreenInfo, s_pScreen); 481#endif 482 483#if CYGDEBUG 484 winDebug ("winChangeDepthDlgProc - WM_INITDIALOG - orig bpp: %d, " 485 "current bpp: %d\n", 486 s_pScreenInfo->dwBPP, 487 GetDeviceCaps(s_pScreenPriv->hdcScreen, BITSPIXEL)); 488#endif 489 490 winInitDialog( hwndDialog ); 491 492 return TRUE; 493 494 case WM_DISPLAYCHANGE: 495#if CYGDEBUG 496 winDebug ("winChangeDepthDlgProc - WM_DISPLAYCHANGE - orig bpp: %d, " 497 "new bpp: %d\n", 498 s_pScreenInfo->dwBPP, 499 GetDeviceCaps(s_pScreenPriv->hdcScreen, BITSPIXEL)); 500#endif 501 502 /* Dismiss the dialog if the display returns to the original depth */ 503 if (GetDeviceCaps(s_pScreenPriv->hdcScreen, BITSPIXEL) == s_pScreenInfo->dwBPP) 504 { 505 ErrorF ("winChangeDelthDlgProc - wParam == s_pScreenInfo->dwBPP\n"); 506 507 /* Depth has been restored, dismiss dialog */ 508 DestroyWindow (g_hDlgDepthChange); 509 g_hDlgDepthChange = NULL; 510 511 /* Flag that we have a valid screen depth */ 512 s_pScreenPriv->fBadDepth = FALSE; 513 } 514 return TRUE; 515 516 case WM_COMMAND: 517 switch (LOWORD (wParam)) 518 { 519 case IDOK: 520 case IDCANCEL: 521 ErrorF ("winChangeDepthDlgProc - WM_COMMAND - IDOK or IDCANCEL\n"); 522 523 /* 524 * User dismissed the dialog, hide it until the 525 * display mode is restored. 526 */ 527 ShowWindow (g_hDlgDepthChange, SW_HIDE); 528 return TRUE; 529 } 530 break; 531 532 case WM_CLOSE: 533 ErrorF ("winChangeDepthDlgProc - WM_CLOSE\n"); 534 535 DestroyWindow (g_hDlgAbout); 536 g_hDlgAbout = NULL; 537 538 /* Fix to make sure keyboard focus isn't trapped */ 539 PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); 540 return TRUE; 541 } 542 543 return FALSE; 544} 545 546 547/* 548 * Display the About dialog box 549 */ 550 551void 552winDisplayAboutDialog (winPrivScreenPtr pScreenPriv) 553{ 554 /* Check if dialog already exists */ 555 if (g_hDlgAbout != NULL) 556 { 557 /* Dialog box already exists, display it */ 558 ShowWindow (g_hDlgAbout, SW_SHOWDEFAULT); 559 560 /* User has lost the dialog. Show them where it is. */ 561 SetForegroundWindow (g_hDlgAbout); 562 563 return; 564 } 565 566 /* 567 * Display the about box 568 */ 569 g_hDlgAbout = CreateDialogParam (g_hInstance, 570 "ABOUT_BOX", 571 pScreenPriv->hwndScreen, 572 winAboutDlgProc, 573 (int) pScreenPriv); 574 575 /* Show the dialog box */ 576 ShowWindow (g_hDlgAbout, SW_SHOW); 577 578 /* Needed to get keyboard controls (tab, arrows, enter, esc) to work */ 579 SetForegroundWindow (g_hDlgAbout); 580 581 /* Set focus to the OK button */ 582 PostMessage (g_hDlgAbout, WM_NEXTDLGCTL, 583 (WPARAM)GetDlgItem (g_hDlgAbout, IDOK), TRUE); 584} 585 586 587/* 588 * Process messages for the about dialog. 589 */ 590 591static wBOOL CALLBACK 592winAboutDlgProc (HWND hwndDialog, UINT message, 593 WPARAM wParam, LPARAM lParam) 594{ 595 static winPrivScreenPtr s_pScreenPriv = NULL; 596 static winScreenInfo *s_pScreenInfo = NULL; 597 static ScreenPtr s_pScreen = NULL; 598 599#if CYGDEBUG 600 winDebug ("winAboutDlgProc\n"); 601#endif 602 603 /* Branch on message type */ 604 switch (message) 605 { 606 case WM_INITDIALOG: 607#if CYGDEBUG 608 winDebug ("winAboutDlgProc - WM_INITDIALOG\n"); 609#endif 610 611 /* Store pointers to private structures for future use */ 612 s_pScreenPriv = (winPrivScreenPtr) lParam; 613 s_pScreenInfo = s_pScreenPriv->pScreenInfo; 614 s_pScreen = s_pScreenInfo->pScreen; 615 616 winInitDialog (hwndDialog); 617 618 /* Override the URL buttons */ 619 winOverrideURLButton (hwndDialog, ID_ABOUT_CHANGELOG); 620 winOverrideURLButton (hwndDialog, ID_ABOUT_WEBSITE); 621 winOverrideURLButton (hwndDialog, ID_ABOUT_UG); 622 winOverrideURLButton (hwndDialog, ID_ABOUT_FAQ); 623 624 return TRUE; 625 626 case WM_DRAWITEM: 627 /* Draw the URL buttons as needed */ 628 winDrawURLWindow (lParam); 629 return TRUE; 630 631 case WM_MOUSEMOVE: 632 case WM_NCMOUSEMOVE: 633 /* Show the cursor if it is hidden */ 634 if (g_fSoftwareCursor && !g_fCursor) 635 { 636 g_fCursor = TRUE; 637 ShowCursor (TRUE); 638 } 639 return TRUE; 640 641 case WM_COMMAND: 642 switch (LOWORD (wParam)) 643 { 644 case IDOK: 645 case IDCANCEL: 646 ErrorF ("winAboutDlgProc - WM_COMMAND - IDOK or IDCANCEL\n"); 647 648 DestroyWindow (g_hDlgAbout); 649 g_hDlgAbout = NULL; 650 651 /* Fix to make sure keyboard focus isn't trapped */ 652 PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); 653 654 /* Restore window procedures for URL buttons */ 655 winUnoverrideURLButton (hwndDialog, ID_ABOUT_CHANGELOG); 656 winUnoverrideURLButton (hwndDialog, ID_ABOUT_WEBSITE); 657 winUnoverrideURLButton (hwndDialog, ID_ABOUT_UG); 658 winUnoverrideURLButton (hwndDialog, ID_ABOUT_FAQ); 659 660 return TRUE; 661 662 case ID_ABOUT_CHANGELOG: 663 { 664 int iReturn; 665#ifdef __CYGWIN__ 666 const char * pszCygPath = "/usr/X11R6/share/doc/" 667 "xorg-x11-xwin/changelog.html"; 668 char pszWinPath[MAX_PATH + 1]; 669 670 /* Convert the POSIX path to a Win32 path */ 671 cygwin_conv_to_win32_path (pszCygPath, pszWinPath); 672#else 673 const char * pszWinPath = "http://x.cygwin.com/" 674 "devel/server/changelog.html"; 675#endif 676 677 iReturn = (int)ShellExecute (NULL, 678 "open", 679 pszWinPath, 680 NULL, 681 NULL, 682 SW_MAXIMIZE); 683 if (iReturn < 32) 684 { 685 ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_CHANGELOG - " 686 "ShellExecute failed: %d\n", 687 iReturn); 688 } 689 } 690 return TRUE; 691 692 case ID_ABOUT_WEBSITE: 693 { 694 const char * pszPath = __VENDORDWEBSUPPORT__; 695 int iReturn; 696 697 iReturn = (int)ShellExecute (NULL, 698 "open", 699 pszPath, 700 NULL, 701 NULL, 702 SW_MAXIMIZE); 703 if (iReturn < 32) 704 { 705 ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_WEBSITE - " 706 "ShellExecute failed: %d\n", 707 iReturn); 708 } 709 } 710 return TRUE; 711 712 case ID_ABOUT_UG: 713 { 714 const char * pszPath = "http://x.cygwin.com/docs/ug/"; 715 int iReturn; 716 717 iReturn = (int)ShellExecute (NULL, 718 "open", 719 pszPath, 720 NULL, 721 NULL, 722 SW_MAXIMIZE); 723 if (iReturn < 32) 724 { 725 ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_UG - " 726 "ShellExecute failed: %d\n", 727 iReturn); 728 } 729 } 730 return TRUE; 731 732 case ID_ABOUT_FAQ: 733 { 734 const char * pszPath = "http://x.cygwin.com/docs/faq/"; 735 int iReturn; 736 737 iReturn = (int)ShellExecute (NULL, 738 "open", 739 pszPath, 740 NULL, 741 NULL, 742 SW_MAXIMIZE); 743 if (iReturn < 32) 744 { 745 ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_FAQ - " 746 "ShellExecute failed: %d\n", 747 iReturn); 748 } 749 } 750 return TRUE; 751 } 752 break; 753 754 case WM_CLOSE: 755 ErrorF ("winAboutDlgProc - WM_CLOSE\n"); 756 757 DestroyWindow (g_hDlgAbout); 758 g_hDlgAbout = NULL; 759 760 /* Fix to make sure keyboard focus isn't trapped */ 761 PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); 762 763 /* Restore window procedures for URL buttons */ 764 winUnoverrideURLButton (hwndDialog, ID_ABOUT_CHANGELOG); 765 winUnoverrideURLButton (hwndDialog, ID_ABOUT_WEBSITE); 766 winUnoverrideURLButton (hwndDialog, ID_ABOUT_UG); 767 winUnoverrideURLButton (hwndDialog, ID_ABOUT_FAQ); 768 769 return TRUE; 770 } 771 772 return FALSE; 773} 774