xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

InitOutput.c (31310B)


      1 
      2 /*
      3 
      4 Copyright 1993, 1998  The Open Group
      5 Copyright (C) Colin Harrison 2005-2008
      6 
      7 Permission to use, copy, modify, distribute, and sell this software and its
      8 documentation for any purpose is hereby granted without fee, provided that
      9 the above copyright notice appear in all copies and that both that
     10 copyright notice and this permission notice appear in supporting
     11 documentation.
     12 
     13 The above copyright notice and this permission notice shall be included
     14 in all copies or substantial portions of the Software.
     15 
     16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     17 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     19 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22 OTHER DEALINGS IN THE SOFTWARE.
     23 
     24 Except as contained in this notice, the name of The Open Group shall
     25 not be used in advertising or otherwise to promote the sale, use or
     26 other dealings in this Software without prior written authorization
     27 from 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")
     53 typedef 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 
     78 void
     79  winLogCommandLine(int argc, char *argv[]);
     80 
     81 void
     82  winLogVersionInfo(void);
     83 
     84 Bool
     85  winValidateArgs(void);
     86 
     87 #ifdef RELOCATE_PROJECTROOT
     88 const 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 
    104 static 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 
    114 static Bool noDriExtension;
    115 
    116 static 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  */
    128 static
    129 void 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 
    147 void
    148 ddxBeforeReset(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. */
    159 void
    160 ddxInputThreadInit(void)
    161 {
    162 }
    163 #endif
    164 
    165 int
    166 main(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 */
    185 void
    186 ddxGiveUp(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 */
    256 static const char *
    257 winCheckMntOpt(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 
    279 static void
    280 winCheckMount(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
    337 static void
    338 winCheckMount(void)
    339 {
    340 }
    341 #endif
    342 
    343 #ifdef RELOCATE_PROJECTROOT
    344 const char *
    345 winGetBaseDir(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 
    372 static void
    373 winFixupPaths(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 
    614 void
    615 OsVendorInit(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 
    705 static void
    706 winUseMsg(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 */
    864 void
    865 ddxUseMsg(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 
    894 void
    895 InitOutput(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 }