winprocarg.c revision 6747b715
1/*
2
3Copyright 1993, 1998  The Open Group
4Copyright (C) Colin Harrison 2005-2008
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included
13in all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
19OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21OTHER DEALINGS IN THE SOFTWARE.
22
23Except as contained in this notice, the name of The Open Group shall
24not be used in advertising or otherwise to promote the sale, use or
25other dealings in this Software without prior written authorization
26from The Open Group.
27
28*/
29
30#ifdef HAVE_XWIN_CONFIG_H
31#include <xwin-config.h>
32#endif
33#ifdef XVENDORNAME
34#define VENDOR_STRING XVENDORNAME
35#define VENDOR_CONTACT BUILDERADDR
36#endif
37#include <../xfree86/common/xorgVersion.h>
38#include "win.h"
39#include "winconfig.h"
40#include "winprefs.h"
41#include "winmsg.h"
42
43/*
44 * References to external symbols
45 */
46
47extern int			g_iNumScreens;
48extern winScreenInfo *		g_ScreenInfo;
49#ifdef XWIN_CLIPBOARD
50extern Bool			g_fUnicodeClipboard;
51extern Bool			g_fClipboard;
52#endif
53extern int			g_iLogVerbose;
54extern const char *		g_pszLogFile;
55#ifdef RELOCATE_PROJECTROOT
56extern Bool			g_fLogFileChanged;
57#endif
58extern Bool			g_fXdmcpEnabled;
59extern Bool			g_fAuthEnabled;
60extern char *			g_pszCommandLine;
61extern Bool			g_fKeyboardHookLL;
62extern Bool			g_fNoHelpMessageBox;
63extern Bool			g_fSoftwareCursor;
64extern Bool			g_fSilentDupError;
65extern Bool                     g_fNativeGl;
66
67/* globals required by callback function for monitor information */
68struct GetMonitorInfoData {
69    int  requestedMonitor;
70    int  monitorNum;
71    Bool bUserSpecifiedMonitor;
72    Bool bMonitorSpecifiedExists;
73    int  monitorOffsetX;
74    int  monitorOffsetY;
75    int  monitorHeight;
76    int  monitorWidth;
77};
78
79typedef wBOOL (*ENUMDISPLAYMONITORSPROC)(HDC,LPCRECT,MONITORENUMPROC,LPARAM);
80ENUMDISPLAYMONITORSPROC _EnumDisplayMonitors;
81
82wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data);
83
84static Bool QueryMonitor(int index, struct GetMonitorInfoData *data)
85{
86    /* Load EnumDisplayMonitors from DLL */
87    HMODULE user32;
88    FARPROC func;
89    user32 = LoadLibrary("user32.dll");
90    if (user32 == NULL)
91    {
92        winW32Error(2, "Could not open user32.dll");
93        return FALSE;
94    }
95    func = GetProcAddress(user32, "EnumDisplayMonitors");
96    if (func == NULL)
97    {
98        winW32Error(2, "Could not resolve EnumDisplayMonitors: ");
99        return FALSE;
100    }
101    _EnumDisplayMonitors = (ENUMDISPLAYMONITORSPROC)func;
102
103    /* prepare data */
104    if (data == NULL)
105        return FALSE;
106    memset(data, 0, sizeof(*data));
107    data->requestedMonitor = index;
108
109    /* query information */
110    _EnumDisplayMonitors(NULL, NULL, getMonitorInfo, (LPARAM) data);
111
112    /* cleanup */
113    FreeLibrary(user32);
114    return TRUE;
115}
116
117/*
118 * Function prototypes
119 */
120
121void
122winLogCommandLine (int argc, char *argv[]);
123
124void
125winLogVersionInfo (void);
126
127#ifdef DDXOSVERRORF
128void OsVendorVErrorF (const char *pszFormat, va_list va_args);
129#endif
130
131/*
132 * Process arguments on the command line
133 */
134
135static int iLastScreen = -1;
136static winScreenInfo defaultScreenInfo;
137
138static void
139winInitializeScreenDefaults(void)
140{
141  DWORD dwWidth, dwHeight;
142  static Bool fInitializedScreenDefaults = FALSE;
143
144  /* Bail out early if default screen has already been initialized */
145  if (fInitializedScreenDefaults)
146    return;
147
148  /* Zero the memory used for storing the screen info */
149  memset(&defaultScreenInfo, 0, sizeof(winScreenInfo));
150
151  /* Get default width and height */
152  /*
153   * NOTE: These defaults will cause the window to cover only
154   * the primary monitor in the case that we have multiple monitors.
155   */
156  dwWidth = GetSystemMetrics (SM_CXSCREEN);
157  dwHeight = GetSystemMetrics (SM_CYSCREEN);
158
159  winErrorFVerb (2, "winInitializeScreenDefaults - w %d h %d\n",
160	  (int) dwWidth, (int) dwHeight);
161
162  /* Set a default DPI, if no parameter was passed */
163  if (monitorResolution == 0)
164    monitorResolution = WIN_DEFAULT_DPI;
165
166  defaultScreenInfo.dwWidth  = dwWidth;
167  defaultScreenInfo.dwHeight = dwHeight;
168  defaultScreenInfo.dwUserWidth  = dwWidth;
169  defaultScreenInfo.dwUserHeight = dwHeight;
170  defaultScreenInfo.fUserGaveHeightAndWidth = WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH;
171  defaultScreenInfo.fUserGavePosition = FALSE;
172  defaultScreenInfo.dwBPP = WIN_DEFAULT_BPP;
173  defaultScreenInfo.dwClipUpdatesNBoxes = WIN_DEFAULT_CLIP_UPDATES_NBOXES;
174#ifdef XWIN_EMULATEPSEUDO
175  defaultScreenInfo.fEmulatePseudo = WIN_DEFAULT_EMULATE_PSEUDO;
176#endif
177  defaultScreenInfo.dwRefreshRate = WIN_DEFAULT_REFRESH;
178  defaultScreenInfo.pfb = NULL;
179  defaultScreenInfo.fFullScreen = FALSE;
180  defaultScreenInfo.fDecoration = TRUE;
181#ifdef XWIN_MULTIWINDOWEXTWM
182  defaultScreenInfo.fMWExtWM = FALSE;
183  defaultScreenInfo.fInternalWM = FALSE;
184#endif
185  defaultScreenInfo.fRootless = FALSE;
186#ifdef XWIN_MULTIWINDOW
187  defaultScreenInfo.fMultiWindow = FALSE;
188#endif
189#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
190  defaultScreenInfo.fMultiMonitorOverride = FALSE;
191#endif
192  defaultScreenInfo.fMultipleMonitors = FALSE;
193  defaultScreenInfo.fLessPointer = FALSE;
194  defaultScreenInfo.fScrollbars = FALSE;
195  defaultScreenInfo.fNoTrayIcon = FALSE;
196  defaultScreenInfo.iE3BTimeout = WIN_E3B_OFF;
197  defaultScreenInfo.dwWidth_mm = (dwWidth / WIN_DEFAULT_DPI) * 25.4;
198  defaultScreenInfo.dwHeight_mm = (dwHeight / WIN_DEFAULT_DPI) * 25.4;
199  defaultScreenInfo.fUseWinKillKey = WIN_DEFAULT_WIN_KILL;
200  defaultScreenInfo.fUseUnixKillKey = WIN_DEFAULT_UNIX_KILL;
201  defaultScreenInfo.fIgnoreInput = FALSE;
202  defaultScreenInfo.fExplicitScreen = FALSE;
203
204  /* Note that the default screen has been initialized */
205  fInitializedScreenDefaults = TRUE;
206}
207
208static void
209winInitializeScreen(int i)
210{
211  winErrorFVerb (2, "winInitializeScreen - %d\n",i);
212
213  /* Initialize default screen values, if needed */
214  winInitializeScreenDefaults();
215
216  /* Copy the default screen info */
217  g_ScreenInfo[i] = defaultScreenInfo;
218
219  /* Set the screen number */
220  g_ScreenInfo[i].dwScreen = i;
221}
222
223void
224winInitializeScreens(int maxscreens)
225{
226  int i;
227  winErrorFVerb (2, "winInitializeScreens - %i\n", maxscreens);
228
229  if (maxscreens > g_iNumScreens)
230    {
231      /* Reallocate the memory for DDX-specific screen info */
232      g_ScreenInfo = realloc(g_ScreenInfo, maxscreens * sizeof (winScreenInfo));
233
234      /* Set default values for any new screens */
235      for (i = g_iNumScreens; i < maxscreens ; i++)
236        winInitializeScreen(i);
237
238      /* Keep a count of the number of screens */
239      g_iNumScreens = maxscreens;
240    }
241}
242
243/* See Porting Layer Definition - p. 57 */
244/*
245 * INPUT
246 * argv: pointer to an array of null-terminated strings, one for
247 *   each token in the X Server command line; the first token
248 *   is 'XWin.exe', or similar.
249 * argc: a count of the number of tokens stored in argv.
250 * i: a zero-based index into argv indicating the current token being
251 *   processed.
252 *
253 * OUTPUT
254 * return: return the number of tokens processed correctly.
255 *
256 * NOTE
257 * When looking for n tokens, check that i + n is less than argc.  Or,
258 *   you may check if i is greater than or equal to argc, in which case
259 *   you should display the UseMsg () and return 0.
260 */
261
262/* Check if enough arguments are given for the option */
263#define CHECK_ARGS(count) if (i + count >= argc) { UseMsg (); return 0; }
264
265/* Compare the current option with the string. */
266#define IS_OPTION(name) (strcmp (argv[i], name) == 0)
267
268int
269ddxProcessArgument (int argc, char *argv[], int i)
270{
271  static Bool		s_fBeenHere = FALSE;
272  winScreenInfo	*screenInfoPtr = NULL;
273
274  /* Initialize once */
275  if (!s_fBeenHere)
276    {
277#ifdef DDXOSVERRORF
278      /*
279       * This initialises our hook into VErrorF () for catching log messages
280       * that are generated before OsInit () is called.
281       */
282      OsVendorVErrorFProc = OsVendorVErrorF;
283#endif
284
285      s_fBeenHere = TRUE;
286
287      /* Initialize only if option is not -help */
288      if (!IS_OPTION("-help") && !IS_OPTION("-h") && !IS_OPTION("--help") &&
289          !IS_OPTION("-version") && !IS_OPTION("--version"))
290	{
291
292          /* Log the version information */
293          winLogVersionInfo ();
294
295          /* Log the command line */
296          winLogCommandLine (argc, argv);
297
298	  /*
299	   * Initialize default screen settings.  We have to do this before
300	   * OsVendorInit () gets called, otherwise we will overwrite
301	   * settings changed by parameters such as -fullscreen, etc.
302	   */
303	  winErrorFVerb (2, "ddxProcessArgument - Initializing default "
304			 "screens\n");
305	  winInitializeScreenDefaults();
306	}
307    }
308
309#if CYGDEBUG
310  winDebug ("ddxProcessArgument - arg: %s\n", argv[i]);
311#endif
312
313  /*
314   * Look for the '-help' and similar options
315   */
316  if (IS_OPTION ("-help") || IS_OPTION("-h") || IS_OPTION("--help"))
317    {
318      /* Reset logfile. We don't need that helpmessage in the logfile */
319      g_pszLogFile = NULL;
320      g_fNoHelpMessageBox = TRUE;
321      UseMsg();
322      exit (0);
323      return 1;
324    }
325
326  if (IS_OPTION ("-version") || IS_OPTION("--version"))
327    {
328      /* Reset logfile. We don't need that versioninfo in the logfile */
329      g_pszLogFile = NULL;
330      winLogVersionInfo ();
331      exit (0);
332      return 1;
333    }
334
335  /*
336   * Look for the '-screen scr_num [width height]' argument
337   */
338  if (IS_OPTION ("-screen"))
339    {
340      int		iArgsProcessed = 1;
341      int		nScreenNum;
342      int		iWidth, iHeight, iX, iY;
343      int		iMonitor;
344
345#if CYGDEBUG
346      winDebug ("ddxProcessArgument - screen - argc: %d i: %d\n",
347	      argc, i);
348#endif
349
350      /* Display the usage message if the argument is malformed */
351      if (i + 1 >= argc)
352	{
353	  return 0;
354	}
355
356      /* Grab screen number */
357      nScreenNum = atoi (argv[i + 1]);
358
359      /* Validate the specified screen number */
360      if (nScreenNum < 0)
361        {
362          ErrorF ("ddxProcessArgument - screen - Invalid screen number %d\n",
363		  nScreenNum);
364          UseMsg ();
365	  return 0;
366        }
367
368      /*
369        Initialize default values for any new screens
370
371        Note that default values can't change after a -screen option is
372        seen, so it's safe to do this for each screen as it is introduced
373      */
374      winInitializeScreens(nScreenNum+1);
375
376	  /* look for @m where m is monitor number */
377	  if (i + 2 < argc
378		  && 1 == sscanf(argv[i + 2], "@%d", (int *) &iMonitor))
379      {
380        struct GetMonitorInfoData data;
381        if (!QueryMonitor(iMonitor, &data))
382        {
383            ErrorF ("ddxProcessArgument - screen - "
384                    "Querying monitors is not supported on NT4 and Win95\n");
385        } else if (data.bMonitorSpecifiedExists == TRUE)
386        {
387		  winErrorFVerb(2, "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor);
388		  iArgsProcessed = 3;
389		  g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE;
390		  g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
391		  g_ScreenInfo[nScreenNum].dwWidth = data.monitorWidth;
392		  g_ScreenInfo[nScreenNum].dwHeight = data.monitorHeight;
393		  g_ScreenInfo[nScreenNum].dwUserWidth = data.monitorWidth;
394		  g_ScreenInfo[nScreenNum].dwUserHeight = data.monitorHeight;
395		  g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX;
396		  g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY;
397		}
398		else
399        {
400		  /* monitor does not exist, error out */
401		  ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n",
402				  iMonitor);
403		  UseMsg ();
404		  exit (0);
405		  return 0;
406		}
407	  }
408
409      /* Look for 'WxD' or 'W D' */
410      else if (i + 2 < argc
411	  && 2 == sscanf (argv[i + 2], "%dx%d",
412			  (int *) &iWidth,
413			  (int *) &iHeight))
414	{
415	  winErrorFVerb (2, "ddxProcessArgument - screen - Found ``WxD'' arg\n");
416	  iArgsProcessed = 3;
417	  g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE;
418	  g_ScreenInfo[nScreenNum].dwWidth = iWidth;
419	  g_ScreenInfo[nScreenNum].dwHeight = iHeight;
420	  g_ScreenInfo[nScreenNum].dwUserWidth = iWidth;
421	  g_ScreenInfo[nScreenNum].dwUserHeight = iHeight;
422	  /* Look for WxD+X+Y */
423	  if (2 == sscanf (argv[i + 2], "%*dx%*d+%d+%d",
424			   (int *) &iX,
425			   (int *) &iY))
426	  {
427	    winErrorFVerb (2, "ddxProcessArgument - screen - Found ``X+Y'' arg\n");
428	    g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
429	    g_ScreenInfo[nScreenNum].dwInitialX = iX;
430	    g_ScreenInfo[nScreenNum].dwInitialY = iY;
431
432		/* look for WxD+X+Y@m where m is monitor number. take X,Y to be offsets from monitor's root position */
433		if (1 == sscanf (argv[i + 2], "%*dx%*d+%*d+%*d@%d",
434						 (int *) &iMonitor))
435        {
436          struct GetMonitorInfoData data;
437          if (!QueryMonitor(iMonitor, &data))
438          {
439              ErrorF ("ddxProcessArgument - screen - "
440                      "Querying monitors is not supported on NT4 and Win95\n");
441          } else if (data.bMonitorSpecifiedExists == TRUE)
442          {
443			g_ScreenInfo[nScreenNum].dwInitialX += data.monitorOffsetX;
444			g_ScreenInfo[nScreenNum].dwInitialY += data.monitorOffsetY;
445		  }
446		  else
447          {
448			/* monitor does not exist, error out */
449			ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n",
450					iMonitor);
451			UseMsg ();
452			exit (0);
453			return 0;
454		  }
455
456		}
457	  }
458
459	  /* look for WxD@m where m is monitor number */
460	  else if (1 == sscanf(argv[i + 2], "%*dx%*d@%d",
461						   (int *) &iMonitor))
462      {
463        struct GetMonitorInfoData data;
464        if (!QueryMonitor(iMonitor, &data))
465        {
466		  ErrorF ("ddxProcessArgument - screen - "
467                  "Querying monitors is not supported on NT4 and Win95\n");
468        } else if (data.bMonitorSpecifiedExists == TRUE)
469        {
470		  winErrorFVerb (2, "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor);
471		  g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
472		  g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX;
473		  g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY;
474		}
475		else
476        {
477		  /* monitor does not exist, error out */
478		  ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n",
479				  iMonitor);
480		  UseMsg ();
481		  exit (0);
482		  return 0;
483		}
484
485	  }
486	}
487      else if (i + 3 < argc
488	       && 1 == sscanf (argv[i + 2], "%d",
489			       (int *) &iWidth)
490	       && 1 == sscanf (argv[i + 3], "%d",
491			       (int *) &iHeight))
492	{
493	  winErrorFVerb (2, "ddxProcessArgument - screen - Found ``W D'' arg\n");
494	  iArgsProcessed = 4;
495	  g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE;
496	  g_ScreenInfo[nScreenNum].dwWidth = iWidth;
497	  g_ScreenInfo[nScreenNum].dwHeight = iHeight;
498	  g_ScreenInfo[nScreenNum].dwUserWidth = iWidth;
499	  g_ScreenInfo[nScreenNum].dwUserHeight = iHeight;
500	  if (i + 5 < argc
501	      && 1 == sscanf (argv[i + 4], "%d",
502			      (int *) &iX)
503	      && 1 == sscanf (argv[i + 5], "%d",
504			      (int *) &iY))
505	  {
506	    winErrorFVerb (2, "ddxProcessArgument - screen - Found ``X Y'' arg\n");
507	    iArgsProcessed = 6;
508	    g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
509	    g_ScreenInfo[nScreenNum].dwInitialX = iX;
510	    g_ScreenInfo[nScreenNum].dwInitialY = iY;
511	  }
512	}
513      else
514	{
515	  winErrorFVerb (2, "ddxProcessArgument - screen - Did not find size arg. "
516		  "dwWidth: %d dwHeight: %d\n",
517		  (int) g_ScreenInfo[nScreenNum].dwWidth,
518		  (int) g_ScreenInfo[nScreenNum].dwHeight);
519	  iArgsProcessed = 2;
520	  g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE;
521	}
522
523      /* Calculate the screen width and height in millimeters */
524      if (g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth)
525	{
526	  g_ScreenInfo[nScreenNum].dwWidth_mm
527	    = (g_ScreenInfo[nScreenNum].dwWidth
528	       / monitorResolution) * 25.4;
529	  g_ScreenInfo[nScreenNum].dwHeight_mm
530	    = (g_ScreenInfo[nScreenNum].dwHeight
531	       / monitorResolution) * 25.4;
532	}
533
534      /* Flag that this screen was explicity specified by the user */
535      g_ScreenInfo[nScreenNum].fExplicitScreen = TRUE;
536
537      /*
538       * Keep track of the last screen number seen, as parameters seen
539       * before a screen number apply to all screens, whereas parameters
540       * seen after a screen number apply to that screen number only.
541       */
542      iLastScreen = nScreenNum;
543
544      return iArgsProcessed;
545    }
546
547
548  /*
549   * Is this parameter attached to a screen or global?
550   *
551   * If the parameter is for all screens (appears before
552   * any -screen option), store it in the default screen
553   * info
554   *
555   * If the parameter is for a single screen (appears
556   * after a -screen option), store it in the screen info
557   * for that screen
558   *
559   */
560  if (iLastScreen == -1)
561    {
562      screenInfoPtr = &defaultScreenInfo;
563    }
564  else
565    {
566      screenInfoPtr = &(g_ScreenInfo[iLastScreen]);
567    }
568
569  /*
570   * Look for the '-engine n' argument
571   */
572  if (IS_OPTION ("-engine"))
573    {
574      DWORD		dwEngine = 0;
575      CARD8		c8OnBits = 0;
576
577      /* Display the usage message if the argument is malformed */
578      if (++i >= argc)
579	{
580	  UseMsg ();
581	  return 0;
582	}
583
584      /* Grab the argument */
585      dwEngine = atoi (argv[i]);
586
587      /* Count the one bits in the engine argument */
588      c8OnBits = winCountBits (dwEngine);
589
590      /* Argument should only have a single bit on */
591      if (c8OnBits != 1)
592	{
593	  UseMsg ();
594	  return 0;
595	}
596
597      screenInfoPtr->dwEnginePreferred = dwEngine;
598
599      /* Indicate that we have processed the argument */
600      return 2;
601    }
602
603  /*
604   * Look for the '-fullscreen' argument
605   */
606  if (IS_OPTION ("-fullscreen"))
607    {
608#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
609          if (!screenInfoPtr->fMultiMonitorOverride)
610            screenInfoPtr->fMultipleMonitors = FALSE;
611#endif
612	  screenInfoPtr->fFullScreen = TRUE;
613
614      /* Indicate that we have processed this argument */
615      return 1;
616    }
617
618  /*
619   * Look for the '-lesspointer' argument
620   */
621  if (IS_OPTION ("-lesspointer"))
622    {
623      screenInfoPtr->fLessPointer = TRUE;
624
625      /* Indicate that we have processed this argument */
626      return 1;
627    }
628
629  /*
630   * Look for the '-nodecoration' argument
631   */
632  if (IS_OPTION ("-nodecoration"))
633    {
634#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
635      if (!screenInfoPtr->fMultiMonitorOverride)
636        screenInfoPtr->fMultipleMonitors = FALSE;
637#endif
638      screenInfoPtr->fDecoration = FALSE;
639
640      /* Indicate that we have processed this argument */
641      return 1;
642    }
643
644#ifdef XWIN_MULTIWINDOWEXTWM
645  /*
646   * Look for the '-mwextwm' argument
647   */
648  if (IS_OPTION ("-mwextwm"))
649    {
650      if (!screenInfoPtr->fMultiMonitorOverride)
651        screenInfoPtr->fMultipleMonitors = TRUE;
652      screenInfoPtr->fMWExtWM = TRUE;
653
654      /* Indicate that we have processed this argument */
655      return 1;
656    }
657  /*
658   * Look for the '-internalwm' argument
659   */
660  if (IS_OPTION ("-internalwm"))
661    {
662      if (!screenInfoPtr->fMultiMonitorOverride)
663        screenInfoPtr->fMultipleMonitors = TRUE;
664      screenInfoPtr->fMWExtWM = TRUE;
665      screenInfoPtr->fInternalWM = TRUE;
666
667      /* Indicate that we have processed this argument */
668      return 1;
669    }
670#endif
671
672  /*
673   * Look for the '-rootless' argument
674   */
675  if (IS_OPTION ("-rootless"))
676    {
677#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
678      if (!screenInfoPtr->fMultiMonitorOverride)
679        screenInfoPtr->fMultipleMonitors = FALSE;
680#endif
681      screenInfoPtr->fRootless = TRUE;
682
683      /* Indicate that we have processed this argument */
684      return 1;
685    }
686
687#ifdef XWIN_MULTIWINDOW
688  /*
689   * Look for the '-multiwindow' argument
690   */
691  if (IS_OPTION ("-multiwindow"))
692    {
693#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
694      if (!screenInfoPtr->fMultiMonitorOverride)
695        screenInfoPtr->fMultipleMonitors = TRUE;
696#endif
697      screenInfoPtr->fMultiWindow = TRUE;
698
699      /* Indicate that we have processed this argument */
700      return 1;
701    }
702#endif
703
704  /*
705   * Look for the '-multiplemonitors' argument
706   */
707  if (IS_OPTION ("-multiplemonitors")
708      || IS_OPTION ("-multimonitors"))
709    {
710#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
711      screenInfoPtr->fMultiMonitorOverride = TRUE;
712#endif
713      screenInfoPtr->fMultipleMonitors = TRUE;
714
715      /* Indicate that we have processed this argument */
716      return 1;
717    }
718
719  /*
720   * Look for the '-nomultiplemonitors' argument
721   */
722  if (IS_OPTION ("-nomultiplemonitors")
723      || IS_OPTION ("-nomultimonitors"))
724    {
725#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
726      screenInfoPtr->fMultiMonitorOverride = TRUE;
727#endif
728      screenInfoPtr->fMultipleMonitors = FALSE;
729
730      /* Indicate that we have processed this argument */
731      return 1;
732    }
733
734
735  /*
736   * Look for the '-scrollbars' argument
737   */
738  if (IS_OPTION ("-scrollbars"))
739    {
740      screenInfoPtr->fScrollbars = TRUE;
741
742      /* Indicate that we have processed this argument */
743      return 1;
744    }
745
746
747#ifdef XWIN_CLIPBOARD
748  /*
749   * Look for the '-clipboard' argument
750   */
751  if (IS_OPTION ("-clipboard"))
752    {
753      /* Now the default, we still accept the arg for backwards compatibility */
754      g_fClipboard = TRUE;
755
756      /* Indicate that we have processed this argument */
757      return 1;
758    }
759
760  /*
761   * Look for the '-noclipboard' argument
762   */
763  if (IS_OPTION ("-noclipboard"))
764    {
765      g_fClipboard = FALSE;
766
767      /* Indicate that we have processed this argument */
768      return 1;
769    }
770#endif
771
772
773  /*
774   * Look for the '-ignoreinput' argument
775   */
776  if (IS_OPTION ("-ignoreinput"))
777    {
778      screenInfoPtr->fIgnoreInput = TRUE;
779
780      /* Indicate that we have processed this argument */
781      return 1;
782    }
783
784  /*
785   * Look for the '-emulate3buttons' argument
786   */
787  if (IS_OPTION ("-emulate3buttons"))
788    {
789      int	iArgsProcessed = 1;
790      int	iE3BTimeout = WIN_DEFAULT_E3B_TIME;
791
792      /* Grab the optional timeout value */
793      if (i + 1 < argc
794	  && 1 == sscanf (argv[i + 1], "%d",
795			  &iE3BTimeout))
796        {
797	  /* Indicate that we have processed the next argument */
798	  iArgsProcessed++;
799        }
800      else
801	{
802	  /*
803	   * sscanf () won't modify iE3BTimeout if it doesn't find
804	   * the specified format; however, I want to be explicit
805	   * about setting the default timeout in such cases to
806	   * prevent some programs (me) from getting confused.
807	   */
808	  iE3BTimeout = WIN_DEFAULT_E3B_TIME;
809	}
810
811      screenInfoPtr->iE3BTimeout = iE3BTimeout;
812
813      /* Indicate that we have processed this argument */
814      return iArgsProcessed;
815    }
816
817  /*
818   * Look for the '-depth n' argument
819   */
820  if (IS_OPTION ("-depth"))
821    {
822      DWORD		dwBPP = 0;
823
824      /* Display the usage message if the argument is malformed */
825      if (++i >= argc)
826	{
827	  UseMsg ();
828	  return 0;
829	}
830
831      /* Grab the argument */
832      dwBPP = atoi (argv[i]);
833
834      screenInfoPtr->dwBPP = dwBPP;
835
836      /* Indicate that we have processed the argument */
837      return 2;
838    }
839
840  /*
841   * Look for the '-refresh n' argument
842   */
843  if (IS_OPTION ("-refresh"))
844    {
845      DWORD		dwRefreshRate = 0;
846
847      /* Display the usage message if the argument is malformed */
848      if (++i >= argc)
849	{
850	  UseMsg ();
851	  return 0;
852	}
853
854      /* Grab the argument */
855      dwRefreshRate = atoi (argv[i]);
856
857      screenInfoPtr->dwRefreshRate = dwRefreshRate;
858
859      /* Indicate that we have processed the argument */
860      return 2;
861    }
862
863  /*
864   * Look for the '-clipupdates num_boxes' argument
865   */
866  if (IS_OPTION ("-clipupdates"))
867    {
868      DWORD		dwNumBoxes = 0;
869
870      /* Display the usage message if the argument is malformed */
871      if (++i >= argc)
872	{
873	  UseMsg ();
874	  return 0;
875	}
876
877      /* Grab the argument */
878      dwNumBoxes = atoi (argv[i]);
879
880      screenInfoPtr->dwClipUpdatesNBoxes = dwNumBoxes;
881
882      /* Indicate that we have processed the argument */
883      return 2;
884    }
885
886#ifdef XWIN_EMULATEPSEUDO
887  /*
888   * Look for the '-emulatepseudo' argument
889   */
890  if (IS_OPTION ("-emulatepseudo"))
891    {
892      screenInfoPtr->fEmulatePseudo = TRUE;
893
894      /* Indicate that we have processed this argument */
895      return 1;
896    }
897#endif
898
899  /*
900   * Look for the '-nowinkill' argument
901   */
902  if (IS_OPTION ("-nowinkill"))
903    {
904      screenInfoPtr->fUseWinKillKey = FALSE;
905
906      /* Indicate that we have processed this argument */
907      return 1;
908    }
909
910  /*
911   * Look for the '-winkill' argument
912   */
913  if (IS_OPTION ("-winkill"))
914    {
915      screenInfoPtr->fUseWinKillKey = TRUE;
916
917      /* Indicate that we have processed this argument */
918      return 1;
919    }
920
921  /*
922   * Look for the '-nounixkill' argument
923   */
924  if (IS_OPTION ("-nounixkill"))
925    {
926      screenInfoPtr->fUseUnixKillKey = FALSE;
927
928      /* Indicate that we have processed this argument */
929      return 1;
930    }
931
932  /*
933   * Look for the '-unixkill' argument
934   */
935  if (IS_OPTION ("-unixkill"))
936    {
937      screenInfoPtr->fUseUnixKillKey = TRUE;
938
939      /* Indicate that we have processed this argument */
940      return 1;
941    }
942
943  /*
944   * Look for the '-notrayicon' argument
945   */
946  if (IS_OPTION ("-notrayicon"))
947    {
948      screenInfoPtr->fNoTrayIcon = TRUE;
949
950      /* Indicate that we have processed this argument */
951      return 1;
952    }
953
954  /*
955   * Look for the '-trayicon' argument
956   */
957  if (IS_OPTION ("-trayicon"))
958    {
959      screenInfoPtr->fNoTrayIcon = FALSE;
960
961      /* Indicate that we have processed this argument */
962      return 1;
963    }
964
965  /*
966   * Look for the '-fp' argument
967   */
968  if (IS_OPTION ("-fp"))
969    {
970      CHECK_ARGS (1);
971      g_cmdline.fontPath = argv[++i];
972      return 0; /* Let DIX parse this again */
973    }
974
975  /*
976   * Look for the '-query' argument
977   */
978  if (IS_OPTION ("-query"))
979    {
980      CHECK_ARGS (1);
981      g_fXdmcpEnabled = TRUE;
982      g_pszQueryHost = argv[++i];
983      return 0; /* Let DIX parse this again */
984    }
985
986  /*
987   * Look for the '-auth' argument
988   */
989  if (IS_OPTION ("-auth"))
990    {
991      g_fAuthEnabled = TRUE;
992      return 0; /* Let DIX parse this again */
993    }
994
995  /*
996   * Look for the '-indirect' or '-broadcast' arguments
997   */
998  if (IS_OPTION ("-indirect")
999      || IS_OPTION ("-broadcast"))
1000    {
1001      g_fXdmcpEnabled = TRUE;
1002      return 0; /* Let DIX parse this again */
1003    }
1004
1005  /*
1006   * Look for the '-config' argument
1007   */
1008  if (IS_OPTION ("-config")
1009      || IS_OPTION ("-xf86config"))
1010    {
1011      CHECK_ARGS (1);
1012#ifdef XWIN_XF86CONFIG
1013      g_cmdline.configFile = argv[++i];
1014#else
1015      winMessageBoxF ("The %s option is not supported in this "
1016		      "release.\n"
1017		      "Ignoring this option and continuing.\n",
1018		      MB_ICONINFORMATION,
1019		      argv[i]);
1020#endif
1021      return 2;
1022    }
1023
1024  /*
1025   * Look for the '-configdir' argument
1026   */
1027  if (IS_OPTION ("-configdir"))
1028    {
1029      CHECK_ARGS (1);
1030#ifdef XWIN_XF86CONFIG
1031      g_cmdline.configDir = argv[++i];
1032#else
1033      winMessageBoxF ("The %s option is not supported in this "
1034		      "release.\n"
1035		      "Ignoring this option and continuing.\n",
1036		      MB_ICONINFORMATION,
1037		      argv[i]);
1038#endif
1039      return 2;
1040    }
1041
1042  /*
1043   * Look for the '-keyboard' argument
1044   */
1045  if (IS_OPTION ("-keyboard"))
1046    {
1047#ifdef XWIN_XF86CONFIG
1048      CHECK_ARGS (1);
1049      g_cmdline.keyboard = argv[++i];
1050#else
1051      winMessageBoxF ("The -keyboard option is not supported in this "
1052		      "release.\n"
1053		      "Ignoring this option and continuing.\n",
1054		      MB_ICONINFORMATION);
1055#endif
1056      return 2;
1057    }
1058
1059  /*
1060   * Look for the '-logfile' argument
1061   */
1062  if (IS_OPTION ("-logfile"))
1063    {
1064      CHECK_ARGS (1);
1065      g_pszLogFile = argv[++i];
1066#ifdef RELOCATE_PROJECTROOT
1067      g_fLogFileChanged = TRUE;
1068#endif
1069      return 2;
1070    }
1071
1072  /*
1073   * Look for the '-logverbose' argument
1074   */
1075  if (IS_OPTION ("-logverbose"))
1076    {
1077      CHECK_ARGS (1);
1078      g_iLogVerbose = atoi(argv[++i]);
1079      return 2;
1080    }
1081
1082#ifdef XWIN_CLIPBOARD
1083  /*
1084   * Look for the '-nounicodeclipboard' argument
1085   */
1086  if (IS_OPTION ("-nounicodeclipboard"))
1087    {
1088      g_fUnicodeClipboard = FALSE;
1089      /* Indicate that we have processed the argument */
1090      return 1;
1091    }
1092#endif
1093
1094  if (IS_OPTION ("-xkbrules"))
1095    {
1096      CHECK_ARGS (1);
1097      g_cmdline.xkbRules = argv[++i];
1098      return 2;
1099    }
1100  if (IS_OPTION ("-xkbmodel"))
1101    {
1102      CHECK_ARGS (1);
1103      g_cmdline.xkbModel = argv[++i];
1104      return 2;
1105    }
1106  if (IS_OPTION ("-xkblayout"))
1107    {
1108      CHECK_ARGS (1);
1109      g_cmdline.xkbLayout = argv[++i];
1110      return 2;
1111    }
1112  if (IS_OPTION ("-xkbvariant"))
1113    {
1114      CHECK_ARGS (1);
1115      g_cmdline.xkbVariant = argv[++i];
1116      return 2;
1117    }
1118  if (IS_OPTION ("-xkboptions"))
1119    {
1120      CHECK_ARGS (1);
1121      g_cmdline.xkbOptions = argv[++i];
1122      return 2;
1123    }
1124
1125  if (IS_OPTION ("-keyhook"))
1126    {
1127      g_fKeyboardHookLL = TRUE;
1128      return 1;
1129    }
1130
1131  if (IS_OPTION ("-nokeyhook"))
1132    {
1133      g_fKeyboardHookLL = FALSE;
1134      return 1;
1135    }
1136
1137  if (IS_OPTION ("-swcursor"))
1138    {
1139      g_fSoftwareCursor = TRUE;
1140      return 1;
1141    }
1142
1143  if (IS_OPTION ("-silent-dup-error"))
1144    {
1145      g_fSilentDupError = TRUE;
1146      return 1;
1147    }
1148
1149  if (IS_OPTION("-wgl"))
1150    {
1151      g_fNativeGl = TRUE;
1152      return 1;
1153    }
1154
1155  if (IS_OPTION("-nowgl"))
1156    {
1157      g_fNativeGl = FALSE;
1158      return 1;
1159    }
1160
1161  return 0;
1162}
1163
1164
1165/*
1166 * winLogCommandLine - Write entire command line to the log file
1167 */
1168
1169void
1170winLogCommandLine (int argc, char *argv[])
1171{
1172  int		i;
1173  int		iSize = 0;
1174  int		iCurrLen = 0;
1175
1176#define CHARS_PER_LINE 60
1177
1178  /* Bail if command line has already been logged */
1179  if (g_pszCommandLine)
1180    return;
1181
1182  /* Count how much memory is needed for concatenated command line */
1183  for (i = 0, iCurrLen = 0; i < argc; ++i)
1184    if (argv[i])
1185      {
1186	/* Adds two characters for lines that overflow */
1187	if ((strlen (argv[i]) < CHARS_PER_LINE
1188	    && iCurrLen + strlen (argv[i]) > CHARS_PER_LINE)
1189	    || strlen (argv[i]) > CHARS_PER_LINE)
1190	  {
1191	    iCurrLen = 0;
1192	    iSize += 2;
1193	  }
1194
1195	/* Add space for item and trailing space */
1196	iSize += strlen (argv[i]) + 1;
1197
1198	/* Update current line length */
1199	iCurrLen += strlen (argv[i]);
1200      }
1201
1202  /* Allocate memory for concatenated command line */
1203  g_pszCommandLine = malloc (iSize + 1);
1204  if (!g_pszCommandLine)
1205    FatalError ("winLogCommandLine - Could not allocate memory for "
1206		"command line string.  Exiting.\n");
1207
1208  /* Set first character to concatenated command line to null */
1209  g_pszCommandLine[0] = '\0';
1210
1211  /* Loop through all args */
1212  for (i = 0, iCurrLen = 0; i < argc; ++i)
1213    {
1214      /* Add a character for lines that overflow */
1215      if ((strlen (argv[i]) < CHARS_PER_LINE
1216	   && iCurrLen + strlen (argv[i]) > CHARS_PER_LINE)
1217	  || strlen (argv[i]) > CHARS_PER_LINE)
1218      {
1219	iCurrLen = 0;
1220
1221	/* Add line break if it fits */
1222	strncat (g_pszCommandLine, "\n ", iSize - strlen (g_pszCommandLine));
1223      }
1224
1225      strncat (g_pszCommandLine, argv[i], iSize - strlen (g_pszCommandLine));
1226      strncat (g_pszCommandLine, " ", iSize - strlen (g_pszCommandLine));
1227
1228      /* Save new line length */
1229      iCurrLen += strlen (argv[i]);
1230    }
1231
1232  ErrorF ("XWin was started with the following command line:\n\n"
1233	  "%s\n\n", g_pszCommandLine);
1234}
1235
1236
1237/*
1238 * winLogVersionInfo - Log Cygwin/X version information
1239 */
1240
1241void
1242winLogVersionInfo (void)
1243{
1244  static Bool		s_fBeenHere = FALSE;
1245
1246  if (s_fBeenHere)
1247    return;
1248  s_fBeenHere = TRUE;
1249
1250  ErrorF ("Welcome to the XWin X Server\n");
1251  ErrorF ("Vendor: %s\n", VENDOR_STRING);
1252  ErrorF ("Release: %d.%d.%d.%d (%d)\n", XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP, XORG_VERSION_CURRENT);
1253  ErrorF ("%s\n\n", BUILDERSTRING);
1254  ErrorF ("Contact: %s\n", VENDOR_CONTACT);
1255}
1256
1257/*
1258 * getMonitorInfo - callback function used to return information from the enumeration of monitors attached
1259 */
1260
1261wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data)
1262{
1263  struct GetMonitorInfoData* data = (struct GetMonitorInfoData*)_data;
1264  // only get data for monitor number specified in <data>
1265  data->monitorNum++;
1266  if (data->monitorNum == data->requestedMonitor)
1267  {
1268	data->bMonitorSpecifiedExists = TRUE;
1269	data->monitorOffsetX = rect->left;
1270	data->monitorOffsetY = rect->top;
1271	data->monitorHeight  = rect->bottom - rect->top;
1272	data->monitorWidth   = rect->right  - rect->left;
1273    return FALSE;
1274  }
1275  return TRUE;
1276}
1277