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