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