xref: /OK3568_Linux_fs/external/xserver/hw/xwin/InitOutput.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 #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")
54 typedef 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 
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 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  */
126 static
XwinExtensionInit(void)127 void 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 
145 void
ddxBeforeReset(void)146 ddxBeforeReset(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. */
157 void
ddxInputThreadInit(void)158 ddxInputThreadInit(void)
159 {
160 }
161 #endif
162 
163 int
main(int argc,char * argv[],char * envp[])164 main(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 */
183 void
ddxGiveUp(enum ExitCode error)184 ddxGiveUp(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 */
253 void
AbortDDX(enum ExitCode error)254 AbortDDX(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 */
264 static const char *
winCheckMntOpt(const struct mntent * mnt,const char * opt)265 winCheckMntOpt(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 
287 static void
winCheckMount(void)288 winCheckMount(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
345 static void
winCheckMount(void)346 winCheckMount(void)
347 {
348 }
349 #endif
350 
351 #ifdef RELOCATE_PROJECTROOT
352 const char *
winGetBaseDir(void)353 winGetBaseDir(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 
380 static void
winFixupPaths(void)381 winFixupPaths(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 
622 void
OsVendorInit(void)623 OsVendorInit(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 
713 static void
winUseMsg(void)714 winUseMsg(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 */
871 void
ddxUseMsg(void)872 ddxUseMsg(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 
901 void
InitOutput(ScreenInfo * pScreenInfo,int argc,char * argv[])902 InitOutput(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