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