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