InitOutput.c revision 1b5d61b8
1 2/* 3 4Copyright 1993, 1998 The Open Group 5Copyright (C) Colin Harrison 2005-2008 6 7Permission to use, copy, modify, distribute, and sell this software and its 8documentation for any purpose is hereby granted without fee, provided that 9the above copyright notice appear in all copies and that both that 10copyright notice and this permission notice appear in supporting 11documentation. 12 13The above copyright notice and this permission notice shall be included 14in all copies or substantial portions of the Software. 15 16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 20OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22OTHER DEALINGS IN THE SOFTWARE. 23 24Except as contained in this notice, the name of The Open Group shall 25not be used in advertising or otherwise to promote the sale, use or 26other dealings in this Software without prior written authorization 27from The Open Group. 28 29*/ 30 31#ifdef HAVE_XWIN_CONFIG_H 32#include <xwin-config.h> 33#endif 34#include "win.h" 35#include "winmsg.h" 36#include "winconfig.h" 37#include "winprefs.h" 38#include "X11/Xlocale.h" 39#ifdef DPMSExtension 40#include "dpmsproc.h" 41#endif 42#ifdef __CYGWIN__ 43#include <mntent.h> 44#endif 45#if defined(WIN32) 46#include "xkbsrv.h" 47#endif 48#ifdef RELOCATE_PROJECTROOT 49#pragma push_macro("Status") 50#undef Status 51#define Status wStatus 52#include <shlobj.h> 53#pragma pop_macro("Status") 54typedef WINAPI HRESULT(*SHGETFOLDERPATHPROC) (HWND hwndOwner, 55 int nFolder, 56 HANDLE hToken, 57 DWORD dwFlags, LPTSTR pszPath); 58#endif 59 60#include "winmonitors.h" 61#include "nonsdk_extinit.h" 62#include "pseudoramiX/pseudoramiX.h" 63 64#include "glx_extinit.h" 65#ifdef XWIN_GLX_WINDOWS 66#include "glx/glwindows.h" 67#include "dri/windowsdri.h" 68#endif 69 70/* 71 * References to external symbols 72 */ 73 74/* 75 * Function prototypes 76 */ 77 78void 79 winLogCommandLine(int argc, char *argv[]); 80 81void 82 winLogVersionInfo(void); 83 84Bool 85 winValidateArgs(void); 86 87#ifdef RELOCATE_PROJECTROOT 88const char *winGetBaseDir(void); 89#endif 90 91/* 92 * For the depth 24 pixmap we default to 32 bits per pixel, but 93 * we change this pixmap format later if we detect that the display 94 * is going to be running at 24 bits per pixel. 95 * 96 * FIXME: On second thought, don't DIBs only support 32 bits per pixel? 97 * DIBs are the underlying bitmap used for DirectDraw surfaces, so it 98 * seems that all pixmap formats with depth 24 would be 32 bits per pixel. 99 * Confirm whether depth 24 DIBs can have 24 bits per pixel, then remove/keep 100 * the bits per pixel adjustment and update this comment to reflect the 101 * situation. Harold Hunt - 2002/07/02 102 */ 103 104static PixmapFormatRec g_PixmapFormats[] = { 105 {1, 1, BITMAP_SCANLINE_PAD}, 106 {4, 8, BITMAP_SCANLINE_PAD}, 107 {8, 8, BITMAP_SCANLINE_PAD}, 108 {15, 16, BITMAP_SCANLINE_PAD}, 109 {16, 16, BITMAP_SCANLINE_PAD}, 110 {24, 32, BITMAP_SCANLINE_PAD}, 111 {32, 32, BITMAP_SCANLINE_PAD} 112}; 113 114static const ExtensionModule xwinExtensions[] = { 115#ifdef GLXEXT 116#ifdef XWIN_WINDOWS_DRI 117 { WindowsDRIExtensionInit, "Windows-DRI", &noDriExtension }, 118#endif 119#endif 120}; 121 122/* 123 * XwinExtensionInit 124 * Initialises Xwin-specific extensions. 125 */ 126static 127void XwinExtensionInit(void) 128{ 129#ifdef XWIN_GLX_WINDOWS 130 if (g_fNativeGl) { 131 /* install the native GL provider */ 132 glxWinPushNativeProvider(); 133 } 134#endif 135 136 LoadExtensionList(xwinExtensions, ARRAY_SIZE(xwinExtensions), TRUE); 137} 138 139#if defined(DDXBEFORERESET) 140/* 141 * Called right before KillAllClients when the server is going to reset, 142 * allows us to shutdown our seperate threads cleanly. 143 */ 144 145void 146ddxBeforeReset(void) 147{ 148 winDebug("ddxBeforeReset - Hello\n"); 149 150 winClipboardShutdown(); 151} 152#endif 153 154int 155main(int argc, char *argv[], char *envp[]) 156{ 157 int iReturn; 158 159 /* Create & acquire the termination mutex */ 160 iReturn = pthread_mutex_init(&g_pmTerminating, NULL); 161 if (iReturn != 0) { 162 ErrorF("ddxMain - pthread_mutex_init () failed: %d\n", iReturn); 163 } 164 165 iReturn = pthread_mutex_lock(&g_pmTerminating); 166 if (iReturn != 0) { 167 ErrorF("ddxMain - pthread_mutex_lock () failed: %d\n", iReturn); 168 } 169 170 return dix_main(argc, argv, envp); 171} 172 173/* See Porting Layer Definition - p. 57 */ 174void 175ddxGiveUp(enum ExitCode error) 176{ 177 int i; 178 179#if CYGDEBUG 180 winDebug("ddxGiveUp\n"); 181#endif 182 183 /* Perform per-screen deinitialization */ 184 for (i = 0; i < g_iNumScreens; ++i) { 185 /* Delete the tray icon */ 186 if (!g_ScreenInfo[i].fNoTrayIcon && g_ScreenInfo[i].pScreen) 187 winDeleteNotifyIcon(winGetScreenPriv(g_ScreenInfo[i].pScreen)); 188 } 189 190 /* Unload libraries for taskbar grouping */ 191 winPropertyStoreDestroy(); 192 193 /* Notify the worker threads we're exiting */ 194 winDeinitMultiWindowWM(); 195 196#ifdef HAS_DEVWINDOWS 197 /* Close our handle to our message queue */ 198 if (g_fdMessageQueue != WIN_FD_INVALID) { 199 /* Close /dev/windows */ 200 close(g_fdMessageQueue); 201 202 /* Set the file handle to invalid */ 203 g_fdMessageQueue = WIN_FD_INVALID; 204 } 205#endif 206 207 if (!g_fLogInited) { 208 g_pszLogFile = LogInit(g_pszLogFile, ".old"); 209 g_fLogInited = TRUE; 210 } 211 LogClose(error); 212 213 /* 214 * At this point we aren't creating any new screens, so 215 * we are guaranteed to not need the DirectDraw functions. 216 */ 217 winReleaseDDProcAddresses(); 218 219 /* Free concatenated command line */ 220 free(g_pszCommandLine); 221 g_pszCommandLine = NULL; 222 223 /* Remove our keyboard hook if it is installed */ 224 winRemoveKeyboardHookLL(); 225 226 /* Tell Windows that we want to end the app */ 227 PostQuitMessage(0); 228 229 { 230 int iReturn = pthread_mutex_unlock(&g_pmTerminating); 231 232 winDebug("ddxGiveUp - Releasing termination mutex\n"); 233 234 if (iReturn != 0) { 235 ErrorF("winMsgWindowProc - pthread_mutex_unlock () failed: %d\n", 236 iReturn); 237 } 238 } 239 240 winDebug("ddxGiveUp - End\n"); 241} 242 243/* See Porting Layer Definition - p. 57 */ 244void 245AbortDDX(enum ExitCode error) 246{ 247#if CYGDEBUG 248 winDebug("AbortDDX\n"); 249#endif 250 ddxGiveUp(error); 251} 252 253#ifdef __CYGWIN__ 254/* hasmntopt is currently not implemented for cygwin */ 255static const char * 256winCheckMntOpt(const struct mntent *mnt, const char *opt) 257{ 258 const char *s; 259 size_t len; 260 261 if (mnt == NULL) 262 return NULL; 263 if (opt == NULL) 264 return NULL; 265 if (mnt->mnt_opts == NULL) 266 return NULL; 267 268 len = strlen(opt); 269 s = strstr(mnt->mnt_opts, opt); 270 if (s == NULL) 271 return NULL; 272 if ((s == mnt->mnt_opts || *(s - 1) == ',') && 273 (s[len] == 0 || s[len] == ',')) 274 return (char *) opt; 275 return NULL; 276} 277 278static void 279winCheckMount(void) 280{ 281 FILE *mnt; 282 struct mntent *ent; 283 284 enum { none = 0, sys_root, user_root, sys_tmp, user_tmp } 285 level = none, curlevel; 286 BOOL binary = TRUE; 287 288 mnt = setmntent("/etc/mtab", "r"); 289 if (mnt == NULL) { 290 ErrorF("setmntent failed"); 291 return; 292 } 293 294 while ((ent = getmntent(mnt)) != NULL) { 295 BOOL sys = (winCheckMntOpt(ent, "user") != NULL); 296 BOOL root = (strcmp(ent->mnt_dir, "/") == 0); 297 BOOL tmp = (strcmp(ent->mnt_dir, "/tmp") == 0); 298 299 if (sys) { 300 if (root) 301 curlevel = sys_root; 302 else if (tmp) 303 curlevel = sys_tmp; 304 else 305 continue; 306 } 307 else { 308 if (root) 309 curlevel = user_root; 310 else if (tmp) 311 curlevel = user_tmp; 312 else 313 continue; 314 } 315 316 if (curlevel <= level) 317 continue; 318 level = curlevel; 319 320 if ((winCheckMntOpt(ent, "binary") == NULL) && 321 (winCheckMntOpt(ent, "binmode") == NULL)) 322 binary = FALSE; 323 else 324 binary = TRUE; 325 } 326 327 if (endmntent(mnt) != 1) { 328 ErrorF("endmntent failed"); 329 return; 330 } 331 332 if (!binary) 333 winMsg(X_WARNING, "/tmp mounted in textmode\n"); 334} 335#else 336static void 337winCheckMount(void) 338{ 339} 340#endif 341 342#ifdef RELOCATE_PROJECTROOT 343const char * 344winGetBaseDir(void) 345{ 346 static BOOL inited = FALSE; 347 static char buffer[MAX_PATH]; 348 349 if (!inited) { 350 char *fendptr; 351 HMODULE module = GetModuleHandle(NULL); 352 DWORD size = GetModuleFileName(module, buffer, sizeof(buffer)); 353 354 if (sizeof(buffer) > 0) 355 buffer[sizeof(buffer) - 1] = 0; 356 357 fendptr = buffer + size; 358 while (fendptr > buffer) { 359 if (*fendptr == '\\' || *fendptr == '/') { 360 *fendptr = 0; 361 break; 362 } 363 fendptr--; 364 } 365 inited = TRUE; 366 } 367 return buffer; 368} 369#endif 370 371static void 372winFixupPaths(void) 373{ 374 BOOL changed_fontpath = FALSE; 375 MessageType font_from = X_DEFAULT; 376 377#ifdef RELOCATE_PROJECTROOT 378 const char *basedir = winGetBaseDir(); 379 size_t basedirlen = strlen(basedir); 380#endif 381 382#ifdef READ_FONTDIRS 383 { 384 /* Open fontpath configuration file */ 385 FILE *fontdirs = fopen(ETCX11DIR "/font-dirs", "rt"); 386 387 if (fontdirs != NULL) { 388 char buffer[256]; 389 int needs_sep = TRUE; 390 int comment_block = FALSE; 391 392 /* get default fontpath */ 393 char *fontpath = strdup(defaultFontPath); 394 size_t size = strlen(fontpath); 395 396 /* read all lines */ 397 while (!feof(fontdirs)) { 398 size_t blen; 399 char *hashchar; 400 char *str; 401 int has_eol = FALSE; 402 403 /* read one line */ 404 str = fgets(buffer, sizeof(buffer), fontdirs); 405 if (str == NULL) /* stop on error or eof */ 406 break; 407 408 if (strchr(str, '\n') != NULL) 409 has_eol = TRUE; 410 411 /* check if block is continued comment */ 412 if (comment_block) { 413 /* ignore all input */ 414 *str = 0; 415 blen = 0; 416 if (has_eol) /* check if line ended in this block */ 417 comment_block = FALSE; 418 } 419 else { 420 /* find comment character. ignore all trailing input */ 421 hashchar = strchr(str, '#'); 422 if (hashchar != NULL) { 423 *hashchar = 0; 424 if (!has_eol) /* mark next block as continued comment */ 425 comment_block = TRUE; 426 } 427 } 428 429 /* strip whitespaces from beginning */ 430 while (*str == ' ' || *str == '\t') 431 str++; 432 433 /* get size, strip whitespaces from end */ 434 blen = strlen(str); 435 while (blen > 0 && (str[blen - 1] == ' ' || 436 str[blen - 1] == '\t' || 437 str[blen - 1] == '\n')) { 438 str[--blen] = 0; 439 } 440 441 /* still something left to add? */ 442 if (blen > 0) { 443 size_t newsize = size + blen; 444 445 /* reserve one character more for ',' */ 446 if (needs_sep) 447 newsize++; 448 449 /* allocate memory */ 450 if (fontpath == NULL) 451 fontpath = malloc(newsize + 1); 452 else 453 fontpath = realloc(fontpath, newsize + 1); 454 455 /* add separator */ 456 if (needs_sep) { 457 fontpath[size] = ','; 458 size++; 459 needs_sep = FALSE; 460 } 461 462 /* mark next line as new entry */ 463 if (has_eol) 464 needs_sep = TRUE; 465 466 /* add block */ 467 strncpy(fontpath + size, str, blen); 468 fontpath[newsize] = 0; 469 size = newsize; 470 } 471 } 472 473 /* cleanup */ 474 fclose(fontdirs); 475 defaultFontPath = strdup(fontpath); 476 free(fontpath); 477 changed_fontpath = TRUE; 478 font_from = X_CONFIG; 479 } 480 } 481#endif /* READ_FONTDIRS */ 482#ifdef RELOCATE_PROJECTROOT 483 { 484 const char *libx11dir = PROJECTROOT "/lib/X11"; 485 size_t libx11dir_len = strlen(libx11dir); 486 char *newfp = NULL; 487 size_t newfp_len = 0; 488 const char *endptr, *ptr, *oldptr = defaultFontPath; 489 490 endptr = oldptr + strlen(oldptr); 491 ptr = strchr(oldptr, ','); 492 if (ptr == NULL) 493 ptr = endptr; 494 while (ptr != NULL) { 495 size_t oldfp_len = (ptr - oldptr); 496 size_t newsize = oldfp_len; 497 char *newpath = malloc(newsize + 1); 498 499 strncpy(newpath, oldptr, newsize); 500 newpath[newsize] = 0; 501 502 if (strncmp(libx11dir, newpath, libx11dir_len) == 0) { 503 char *compose; 504 505 newsize = newsize - libx11dir_len + basedirlen; 506 compose = malloc(newsize + 1); 507 strcpy(compose, basedir); 508 strncat(compose, newpath + libx11dir_len, newsize - basedirlen); 509 compose[newsize] = 0; 510 free(newpath); 511 newpath = compose; 512 } 513 514 oldfp_len = newfp_len; 515 if (oldfp_len > 0) 516 newfp_len++; /* space for separator */ 517 newfp_len += newsize; 518 519 if (newfp == NULL) 520 newfp = malloc(newfp_len + 1); 521 else 522 newfp = realloc(newfp, newfp_len + 1); 523 524 if (oldfp_len > 0) { 525 strcpy(newfp + oldfp_len, ","); 526 oldfp_len++; 527 } 528 strcpy(newfp + oldfp_len, newpath); 529 530 free(newpath); 531 532 if (*ptr == 0) { 533 oldptr = ptr; 534 ptr = NULL; 535 } 536 else { 537 oldptr = ptr + 1; 538 ptr = strchr(oldptr, ','); 539 if (ptr == NULL) 540 ptr = endptr; 541 } 542 } 543 544 defaultFontPath = strdup(newfp); 545 free(newfp); 546 changed_fontpath = TRUE; 547 } 548#endif /* RELOCATE_PROJECTROOT */ 549 if (changed_fontpath) 550 winMsg(font_from, "FontPath set to \"%s\"\n", defaultFontPath); 551 552#ifdef RELOCATE_PROJECTROOT 553 if (getenv("XKEYSYMDB") == NULL) { 554 char buffer[MAX_PATH]; 555 556 snprintf(buffer, sizeof(buffer), "XKEYSYMDB=%s\\XKeysymDB", basedir); 557 buffer[sizeof(buffer) - 1] = 0; 558 putenv(buffer); 559 } 560 if (getenv("XERRORDB") == NULL) { 561 char buffer[MAX_PATH]; 562 563 snprintf(buffer, sizeof(buffer), "XERRORDB=%s\\XErrorDB", basedir); 564 buffer[sizeof(buffer) - 1] = 0; 565 putenv(buffer); 566 } 567 if (getenv("XLOCALEDIR") == NULL) { 568 char buffer[MAX_PATH]; 569 570 snprintf(buffer, sizeof(buffer), "XLOCALEDIR=%s\\locale", basedir); 571 buffer[sizeof(buffer) - 1] = 0; 572 putenv(buffer); 573 } 574 if (getenv("HOME") == NULL) { 575 char buffer[MAX_PATH + 5]; 576 577 strncpy(buffer, "HOME=", 5); 578 579 /* query appdata directory */ 580 if (SHGetFolderPathA 581 (NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, 582 buffer + 5) == 0) { 583 putenv(buffer); 584 } 585 else { 586 winMsg(X_ERROR, "Can not determine HOME directory\n"); 587 } 588 } 589 if (!g_fLogFileChanged) { 590 static char buffer[MAX_PATH]; 591 DWORD size = GetTempPath(sizeof(buffer), buffer); 592 593 if (size && size < sizeof(buffer)) { 594 snprintf(buffer + size, sizeof(buffer) - size, 595 "XWin.%s.log", display); 596 buffer[sizeof(buffer) - 1] = 0; 597 g_pszLogFile = buffer; 598 winMsg(X_DEFAULT, "Logfile set to \"%s\"\n", g_pszLogFile); 599 } 600 } 601 { 602 static char xkbbasedir[MAX_PATH]; 603 604 snprintf(xkbbasedir, sizeof(xkbbasedir), "%s\\xkb", basedir); 605 if (sizeof(xkbbasedir) > 0) 606 xkbbasedir[sizeof(xkbbasedir) - 1] = 0; 607 XkbBaseDirectory = xkbbasedir; 608 XkbBinDirectory = basedir; 609 } 610#endif /* RELOCATE_PROJECTROOT */ 611} 612 613void 614OsVendorInit(void) 615{ 616 /* Re-initialize global variables on server reset */ 617 winInitializeGlobals(); 618 619 winFixupPaths(); 620 621#ifdef DDXOSVERRORF 622 if (!OsVendorVErrorFProc) 623 OsVendorVErrorFProc = OsVendorVErrorF; 624#endif 625 626 if (!g_fLogInited) { 627 /* keep this order. If LogInit fails it calls Abort which then calls 628 * ddxGiveUp where LogInit is called again and creates an infinite 629 * recursion. If we set g_fLogInited to TRUE before the init we 630 * avoid the second call 631 */ 632 g_fLogInited = TRUE; 633 g_pszLogFile = LogInit(g_pszLogFile, ".old"); 634 635 } 636 LogSetParameter(XLOG_FLUSH, 1); 637 LogSetParameter(XLOG_VERBOSITY, g_iLogVerbose); 638 LogSetParameter(XLOG_FILE_VERBOSITY, g_iLogVerbose); 639 640 /* Log the version information */ 641 if (serverGeneration == 1) 642 winLogVersionInfo(); 643 644 winCheckMount(); 645 646 /* Add a default screen if no screens were specified */ 647 if (g_iNumScreens == 0) { 648 winDebug("OsVendorInit - Creating default screen 0\n"); 649 650 /* 651 * We need to initialize the default screen 0 if no -screen 652 * arguments were processed. 653 * 654 * Add a screen 0 using the defaults set by winInitializeDefaultScreens() 655 * and any additional default screen parameters given 656 */ 657 winInitializeScreens(1); 658 659 /* We have to flag this as an explicit screen, even though it isn't */ 660 g_ScreenInfo[0].fExplicitScreen = TRUE; 661 } 662 663 /* Work out what the default emulate3buttons setting should be, and apply 664 it if nothing was explicitly specified */ 665 { 666 int mouseButtons = GetSystemMetrics(SM_CMOUSEBUTTONS); 667 int j; 668 669 for (j = 0; j < g_iNumScreens; j++) { 670 if (g_ScreenInfo[j].iE3BTimeout == WIN_E3B_DEFAULT) { 671 if (mouseButtons < 3) { 672 static Bool reportOnce = TRUE; 673 674 g_ScreenInfo[j].iE3BTimeout = WIN_DEFAULT_E3B_TIME; 675 if (reportOnce) { 676 reportOnce = FALSE; 677 winMsg(X_PROBED, 678 "Windows reports only %d mouse buttons, defaulting to -emulate3buttons\n", 679 mouseButtons); 680 } 681 } 682 else { 683 g_ScreenInfo[j].iE3BTimeout = WIN_E3B_OFF; 684 } 685 } 686 } 687 } 688 689 /* Work out what the default resize setting should be, and apply it if it 690 was not explicitly specified */ 691 { 692 int j; 693 for (j = 0; j < g_iNumScreens; j++) { 694 if (g_ScreenInfo[j].iResizeMode == resizeDefault) { 695 if (g_ScreenInfo[j].fFullScreen) 696 g_ScreenInfo[j].iResizeMode = resizeNotAllowed; 697 else 698 g_ScreenInfo[j].iResizeMode = resizeWithRandr; 699 } 700 } 701 } 702} 703 704static void 705winUseMsg(void) 706{ 707 ErrorF("\n"); 708 ErrorF("\n"); 709 ErrorF(EXECUTABLE_NAME " Device Dependent Usage:\n"); 710 ErrorF("\n"); 711 712 ErrorF("-[no]clipboard\n" 713 "\tEnable [disable] the clipboard integration. Default is enabled.\n"); 714 715 ErrorF("-clipupdates num_boxes\n" 716 "\tUse a clipping region to constrain shadow update blits to\n" 717 "\tthe updated region when num_boxes, or more, are in the\n" 718 "\tupdated region.\n"); 719 720#ifdef XWIN_XF86CONFIG 721 ErrorF("-config\n" "\tSpecify a configuration file.\n"); 722 723 ErrorF("-configdir\n" "\tSpecify a configuration directory.\n"); 724#endif 725 726 ErrorF("-depth bits_per_pixel\n" 727 "\tSpecify an optional bitdepth to use in fullscreen mode\n" 728 "\twith a DirectDraw engine.\n"); 729 730 ErrorF("-[no]emulate3buttons [timeout]\n" 731 "\tEmulate 3 button mouse with an optional timeout in\n" 732 "\tmilliseconds.\n"); 733 734#ifdef XWIN_EMULATEPSEUDO 735 ErrorF("-emulatepseudo\n" 736 "\tCreate a depth 8 PseudoColor visual when running in\n" 737 "\tdepths 15, 16, 24, or 32, collectively known as TrueColor\n" 738 "\tdepths. The PseudoColor visual does not have correct colors,\n" 739 "\tand it may crash, but it at least allows you to run your\n" 740 "\tapplication in TrueColor modes.\n"); 741#endif 742 743 ErrorF("-engine engine_type_id\n" 744 "\tOverride the server's automatically selected engine type:\n" 745 "\t\t1 - Shadow GDI\n" 746 "\t\t4 - Shadow DirectDraw4 Non-Locking\n" 747 ); 748 749 ErrorF("-fullscreen\n" "\tRun the server in fullscreen mode.\n"); 750 751 ErrorF("-[no]hostintitle\n" 752 "\tIn multiwindow mode, add remote host names to window titles.\n"); 753 754 ErrorF("-ignoreinput\n" "\tIgnore keyboard and mouse input.\n"); 755 756#ifdef XWIN_XF86CONFIG 757 ErrorF("-keyboard\n" 758 "\tSpecify a keyboard device from the configuration file.\n"); 759#endif 760 761 ErrorF("-[no]keyhook\n" 762 "\tGrab special Windows keypresses like Alt-Tab or the Menu " 763 "key.\n"); 764 765 ErrorF("-lesspointer\n" 766 "\tHide the windows mouse pointer when it is over any\n" 767 "\t" EXECUTABLE_NAME 768 " window. This prevents ghost cursors appearing when\n" 769 "\tthe Windows cursor is drawn on top of the X cursor\n"); 770 771 ErrorF("-logfile filename\n" "\tWrite log messages to <filename>.\n"); 772 773 ErrorF("-logverbose verbosity\n" 774 "\tSet the verbosity of log messages. [NOTE: Only a few messages\n" 775 "\trespect the settings yet]\n" 776 "\t\t0 - only print fatal error.\n" 777 "\t\t1 - print additional configuration information.\n" 778 "\t\t2 - print additional runtime information [default].\n" 779 "\t\t3 - print debugging and tracing information.\n"); 780 781 ErrorF("-[no]multimonitors or -[no]multiplemonitors\n" 782 "\tUse the entire virtual screen if multiple\n" 783 "\tmonitors are present.\n"); 784 785 ErrorF("-multiwindow\n" "\tRun the server in multi-window mode.\n"); 786 787#ifdef XWIN_MULTIWINDOWEXTWM 788 ErrorF("-mwextwm\n" 789 "\tRun the server in multi-window external window manager mode.\n"); 790#endif 791 792 ErrorF("-nodecoration\n" 793 "\tDo not draw a window border, title bar, etc. Windowed\n" 794 "\tmode only.\n"); 795 796 ErrorF("-nounicodeclipboard\n" 797 "\tDo not use Unicode clipboard even if on a NT-based platform.\n"); 798 799 ErrorF("-[no]primary\n" 800 "\tWhen clipboard integration is enabled, map the X11 PRIMARY selection\n" 801 "\tto the Windows clipboard. Default is enabled.\n"); 802 803 ErrorF("-refresh rate_in_Hz\n" 804 "\tSpecify an optional refresh rate to use in fullscreen mode\n" 805 "\twith a DirectDraw engine.\n"); 806 807 ErrorF("-resize=none|scrollbars|randr" 808 "\tIn windowed mode, [don't] allow resizing of the window. 'scrollbars'\n" 809 "\tmode gives the window scrollbars as needed, 'randr' mode uses the RANR\n" 810 "\textension to resize the X screen. 'randr' is the default.\n"); 811 812 ErrorF("-rootless\n" "\tRun the server in rootless mode.\n"); 813 814 ErrorF("-screen scr_num [width height [x y] | [[WxH[+X+Y]][@m]] ]\n" 815 "\tEnable screen scr_num and optionally specify a width and\n" 816 "\theight and initial position for that screen. Additionally\n" 817 "\ta monitor number can be specified to start the server on,\n" 818 "\tat which point, all coordinates become relative to that\n" 819 "\tmonitor. Examples:\n" 820 "\t -screen 0 800x600+100+100@2 ; 2nd monitor offset 100,100 size 800x600\n" 821 "\t -screen 0 1024x768@3 ; 3rd monitor size 1024x768\n" 822 "\t -screen 0 @1 ; on 1st monitor using its full resolution (the default)\n"); 823 824 ErrorF("-swcursor\n" 825 "\tDisable the usage of the Windows cursor and use the X11 software\n" 826 "\tcursor instead.\n"); 827 828 ErrorF("-[no]trayicon\n" 829 "\tDo not create a tray icon. Default is to create one\n" 830 "\ticon per screen. You can globally disable tray icons with\n" 831 "\t-notrayicon, then enable it for specific screens with\n" 832 "\t-trayicon for those screens.\n"); 833 834 ErrorF("-[no]unixkill\n" "\tCtrl+Alt+Backspace exits the X Server.\n"); 835 836#ifdef XWIN_GLX_WINDOWS 837 ErrorF("-[no]wgl\n" 838 "\tEnable the GLX extension to use the native Windows WGL interface for hardware-accelerated OpenGL\n"); 839#endif 840 841 ErrorF("-[no]winkill\n" "\tAlt+F4 exits the X Server.\n"); 842 843 ErrorF("-xkblayout XKBLayout\n" 844 "\tEquivalent to XKBLayout in XF86Config files.\n" 845 "\tFor example: -xkblayout de\n"); 846 847 ErrorF("-xkbmodel XKBModel\n" 848 "\tEquivalent to XKBModel in XF86Config files.\n"); 849 850 ErrorF("-xkboptions XKBOptions\n" 851 "\tEquivalent to XKBOptions in XF86Config files.\n"); 852 853 ErrorF("-xkbrules XKBRules\n" 854 "\tEquivalent to XKBRules in XF86Config files.\n"); 855 856 ErrorF("-xkbvariant XKBVariant\n" 857 "\tEquivalent to XKBVariant in XF86Config files.\n" 858 "\tFor example: -xkbvariant nodeadkeys\n"); 859} 860 861/* See Porting Layer Definition - p. 57 */ 862void 863ddxUseMsg(void) 864{ 865 /* Set a flag so that FatalError won't give duplicate warning message */ 866 g_fSilentFatalError = TRUE; 867 868 winUseMsg(); 869 870 /* Log file will not be opened for UseMsg unless we open it now */ 871 if (!g_fLogInited) { 872 g_pszLogFile = LogInit(g_pszLogFile, ".old"); 873 g_fLogInited = TRUE; 874 } 875 LogClose(EXIT_NO_ERROR); 876 877 /* Notify user where UseMsg text can be found. */ 878 if (!g_fNoHelpMessageBox) 879 winMessageBoxF("The " PROJECT_NAME " help text has been printed to " 880 "%s.\n" 881 "Please open %s to read the help text.\n", 882 MB_ICONINFORMATION, g_pszLogFile, g_pszLogFile); 883} 884 885/* See Porting Layer Definition - p. 20 */ 886/* 887 * Do any global initialization, then initialize each screen. 888 * 889 * NOTE: We use ddxProcessArgument, so we don't need to touch argc and argv 890 */ 891 892void 893InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[]) 894{ 895 int i; 896 897 if (serverGeneration == 1) 898 XwinExtensionInit(); 899 900 /* Log the command line */ 901 winLogCommandLine(argc, argv); 902 903#if CYGDEBUG 904 winDebug("InitOutput\n"); 905#endif 906 907 /* Validate command-line arguments */ 908 if (serverGeneration == 1 && !winValidateArgs()) { 909 FatalError("InitOutput - Invalid command-line arguments found. " 910 "Exiting.\n"); 911 } 912 913#ifdef XWIN_XF86CONFIG 914 /* Try to read the xorg.conf-style configuration file */ 915 if (!winReadConfigfile()) 916 winErrorFVerb(1, "InitOutput - Error reading config file\n"); 917#else 918 winMsg(X_INFO, "xorg.conf is not supported\n"); 919 winMsg(X_INFO, "See http://x.cygwin.com/docs/faq/cygwin-x-faq.html " 920 "for more information\n"); 921 winConfigFiles(); 922#endif 923 924 /* Load preferences from XWinrc file */ 925 LoadPreferences(); 926 927 /* Setup global screen info parameters */ 928 pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER; 929 pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; 930 pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; 931 pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; 932 pScreenInfo->numPixmapFormats = ARRAY_SIZE(g_PixmapFormats); 933 934 /* Describe how we want common pixmap formats padded */ 935 for (i = 0; i < ARRAY_SIZE(g_PixmapFormats); i++) { 936 pScreenInfo->formats[i] = g_PixmapFormats[i]; 937 } 938 939 /* Load pointers to DirectDraw functions */ 940 winGetDDProcAddresses(); 941 942 /* Detect supported engines */ 943 winDetectSupportedEngines(); 944 /* Load libraries for taskbar grouping */ 945 winPropertyStoreInit(); 946 947 /* Store the instance handle */ 948 g_hInstance = GetModuleHandle(NULL); 949 950 /* Create the messaging window */ 951 if (serverGeneration == 1) 952 winCreateMsgWindowThread(); 953 954 /* Initialize each screen */ 955 for (i = 0; i < g_iNumScreens; ++i) { 956 /* Initialize the screen */ 957 if (-1 == AddScreen(winScreenInit, argc, argv)) { 958 FatalError("InitOutput - Couldn't add screen %d", i); 959 } 960 } 961 962 /* 963 Unless full xinerama has been explicitly enabled, register all native screens with pseudoramiX 964 */ 965 if (!noPanoramiXExtension) 966 noPseudoramiXExtension = TRUE; 967 968 if ((g_ScreenInfo[0].fMultipleMonitors) && !noPseudoramiXExtension) 969 { 970 int pass; 971 972 PseudoramiXExtensionInit(); 973 974 /* Add primary monitor on pass 0, other monitors on pass 1, to ensure 975 the primary monitor is first in XINERAMA list */ 976 for (pass = 0; pass < 2; pass++) 977 { 978 int iMonitor; 979 980 for (iMonitor = 1; ; iMonitor++) 981 { 982 struct GetMonitorInfoData data; 983 QueryMonitor(iMonitor, &data); 984 if (data.bMonitorSpecifiedExists) 985 { 986 MONITORINFO mi; 987 mi.cbSize = sizeof(MONITORINFO); 988 989 if (GetMonitorInfo(data.monitorHandle, &mi)) 990 { 991 /* pass == 1 XOR primary monitor flags is set */ 992 if ((!(pass == 1)) != (!(mi.dwFlags & MONITORINFOF_PRIMARY))) 993 { 994 /* 995 Note the screen origin in a normalized coordinate space where (0,0) is at the top left 996 of the native virtual desktop area 997 */ 998 data.monitorOffsetX = data.monitorOffsetX - GetSystemMetrics(SM_XVIRTUALSCREEN); 999 data.monitorOffsetY = data.monitorOffsetY - GetSystemMetrics(SM_YVIRTUALSCREEN); 1000 1001 winDebug ("InitOutput - screen %d added at virtual desktop coordinate (%d,%d) (pseudoramiX) \n", 1002 iMonitor-1, data.monitorOffsetX, data.monitorOffsetY); 1003 1004 PseudoramiXAddScreen(data.monitorOffsetX, data.monitorOffsetY, 1005 data.monitorWidth, data.monitorHeight); 1006 } 1007 } 1008 } 1009 else 1010 break; 1011 } 1012 } 1013 } 1014 1015 xorgGlxCreateVendor(); 1016 1017 /* Generate a cookie used by internal clients for authorization */ 1018 if (g_fXdmcpEnabled || g_fAuthEnabled) 1019 winGenerateAuthorization(); 1020 1021 /* Perform some one time initialization */ 1022 if (1 == serverGeneration) { 1023 /* 1024 * setlocale applies to all threads in the current process. 1025 * Apply locale specified in LANG environment variable. 1026 */ 1027 setlocale(LC_ALL, ""); 1028 } 1029 1030#if CYGDEBUG || YES 1031 winDebug("InitOutput - Returning.\n"); 1032#endif 1033} 1034