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