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